mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Synthetics] Create SLO from Synthetics app for monitors !! (#188835)
## Summary Fixes https://github.com/elastic/kibana/issues/178449 Create SLO from Synthetics app for monitors !! <img width="1446" alt="image" src="https://github.com/user-attachments/assets/c8224faf-cae3-4163-8a26-2c2db27e35f3"> https://github.com/user-attachments/assets/4eaf9777-e031-43cb-a41b-6aa67c41268c --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
91d64f0481
commit
67b8d98619
9 changed files with 137 additions and 45 deletions
|
@ -35,14 +35,14 @@ export function useCreateRule<Params extends RuleTypeParams = never>() {
|
|||
body,
|
||||
});
|
||||
} catch (e) {
|
||||
throw new Error(`Unable to create rule: ${e}`);
|
||||
throw new Error(`Unable to create burn rate rule: ${e}`);
|
||||
}
|
||||
},
|
||||
{
|
||||
onError: (_err) => {
|
||||
toasts.addDanger(
|
||||
i18n.translate('xpack.slo.rules.createRule.errorNotification.descriptionText', {
|
||||
defaultMessage: 'Failed to create rule',
|
||||
defaultMessage: 'Failed to create burn rate rule.',
|
||||
})
|
||||
);
|
||||
},
|
||||
|
@ -50,7 +50,7 @@ export function useCreateRule<Params extends RuleTypeParams = never>() {
|
|||
onSuccess: () => {
|
||||
toasts.addSuccess(
|
||||
i18n.translate('xpack.slo.rules.createRule.successNotification.descriptionText', {
|
||||
defaultMessage: 'Rule created',
|
||||
defaultMessage: 'Burn rate rule created successfully.',
|
||||
})
|
||||
);
|
||||
},
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
"cloud",
|
||||
"data",
|
||||
"fleet",
|
||||
"slo",
|
||||
"home",
|
||||
"ml",
|
||||
"serverless",
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useState } from 'react';
|
||||
import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants';
|
||||
import { ClientPluginsStart } from '../../../../../plugin';
|
||||
|
||||
export function useCreateSLO({
|
||||
configId,
|
||||
label,
|
||||
tags,
|
||||
}: {
|
||||
configId: string;
|
||||
label: string;
|
||||
tags: string[];
|
||||
}) {
|
||||
const { slo } = useKibana<ClientPluginsStart>().services;
|
||||
|
||||
const [isSLOFlyoutOpen, setIsSLOFlyoutOpen] = useState(false);
|
||||
|
||||
const CreateSLOFlyout = slo?.getCreateSLOFlyout({
|
||||
initialValues: {
|
||||
name: `SLO for monitor ${label}`,
|
||||
indicator: {
|
||||
type: 'sli.synthetics.availability',
|
||||
params: {
|
||||
index: SYNTHETICS_INDEX_PATTERN,
|
||||
filter: '',
|
||||
monitorIds: [
|
||||
{
|
||||
value: configId,
|
||||
label,
|
||||
},
|
||||
],
|
||||
projects: [],
|
||||
tags: [],
|
||||
},
|
||||
},
|
||||
budgetingMethod: 'occurrences',
|
||||
objective: {
|
||||
target: 0.99,
|
||||
},
|
||||
tags: tags || [],
|
||||
groupBy: ['monitor.name', 'observer.geo.name', 'monitor.id'],
|
||||
},
|
||||
onClose: () => {
|
||||
setIsSLOFlyoutOpen(false);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
CreateSLOFlyout: isSLOFlyoutOpen ? CreateSLOFlyout : null,
|
||||
setIsSLOFlyoutOpen,
|
||||
};
|
||||
}
|
|
@ -20,6 +20,7 @@ import { FETCH_STATUS } from '@kbn/observability-shared-plugin/public';
|
|||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import styled from 'styled-components';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useCreateSLO } from '../../hooks/use_create_slo';
|
||||
import { TEST_SCHEDULED_LABEL } from '../../../monitor_add_edit/form/run_test_btn';
|
||||
import { useCanUsePublicLocById } from '../../hooks/use_can_use_public_loc_id';
|
||||
import { toggleStatusAlert } from '../../../../../../../common/runtime_types/monitor_management/alert_config';
|
||||
|
@ -136,6 +137,11 @@ export function ActionsPopover({
|
|||
});
|
||||
|
||||
const { alertStatus, updateAlertEnabledState } = useMonitorAlertEnable();
|
||||
const { CreateSLOFlyout, setIsSLOFlyoutOpen } = useCreateSLO({
|
||||
configId: monitor.configId,
|
||||
label: monitor.name,
|
||||
tags: monitor.tags,
|
||||
});
|
||||
|
||||
const [enableLabel, setEnableLabel] = useState(
|
||||
monitor.isEnabled ? disableMonitorLabel : enableMonitorLabel
|
||||
|
@ -220,6 +226,20 @@ export function ActionsPopover({
|
|||
href: http?.basePath.prepend(`synthetics/add-monitor?cloneId=${monitor.configId}`),
|
||||
'data-test-subj': 'cloneMonitorLink',
|
||||
},
|
||||
{
|
||||
name: (
|
||||
<NoPermissionsTooltip canEditSynthetics={canEditSynthetics}>
|
||||
{CREATE_SLO}
|
||||
</NoPermissionsTooltip>
|
||||
),
|
||||
icon: 'visGauge',
|
||||
disabled: !canEditSynthetics || !isServiceAllowed,
|
||||
onClick: () => {
|
||||
setIsPopoverOpen(false);
|
||||
setIsSLOFlyoutOpen(true);
|
||||
},
|
||||
'data-test-subj': 'createSLOBtn',
|
||||
},
|
||||
{
|
||||
name: (
|
||||
<NoPermissionsTooltip
|
||||
|
@ -274,40 +294,43 @@ export function ActionsPopover({
|
|||
if (isInspectView) popoverItems = popoverItems.filter((i) => i !== quickInspectPopoverItem);
|
||||
|
||||
return (
|
||||
<Container boxShadow={euiShadow} position={position}>
|
||||
<EuiPopover
|
||||
button={
|
||||
<IconPanel hasPanel={iconHasPanel}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj="syntheticsActionsPopoverButton"
|
||||
aria-label={openActionsMenuAria}
|
||||
iconType="boxesHorizontal"
|
||||
color="primary"
|
||||
size={iconSize}
|
||||
display="empty"
|
||||
onClick={() => setIsPopoverOpen((b: boolean) => !b)}
|
||||
title={openActionsMenuAria}
|
||||
/>
|
||||
</IconPanel>
|
||||
}
|
||||
color="lightestShade"
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={() => setIsPopoverOpen(false)}
|
||||
anchorPosition="rightUp"
|
||||
panelPaddingSize="none"
|
||||
>
|
||||
<EuiContextMenu
|
||||
initialPanelId={0}
|
||||
panels={[
|
||||
{
|
||||
id: '0',
|
||||
title: actionsMenuTitle,
|
||||
items: popoverItems,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</EuiPopover>
|
||||
</Container>
|
||||
<>
|
||||
<Container boxShadow={euiShadow} position={position}>
|
||||
<EuiPopover
|
||||
button={
|
||||
<IconPanel hasPanel={iconHasPanel}>
|
||||
<EuiButtonIcon
|
||||
data-test-subj="syntheticsActionsPopoverButton"
|
||||
aria-label={openActionsMenuAria}
|
||||
iconType="boxesHorizontal"
|
||||
color="primary"
|
||||
size={iconSize}
|
||||
display="empty"
|
||||
onClick={() => setIsPopoverOpen((b: boolean) => !b)}
|
||||
title={openActionsMenuAria}
|
||||
/>
|
||||
</IconPanel>
|
||||
}
|
||||
color="lightestShade"
|
||||
isOpen={isPopoverOpen}
|
||||
closePopover={() => setIsPopoverOpen(false)}
|
||||
anchorPosition="rightUp"
|
||||
panelPaddingSize="none"
|
||||
>
|
||||
<EuiContextMenu
|
||||
initialPanelId={0}
|
||||
panels={[
|
||||
{
|
||||
id: '0',
|
||||
title: actionsMenuTitle,
|
||||
items: popoverItems,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</EuiPopover>
|
||||
</Container>
|
||||
{CreateSLOFlyout}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -356,6 +379,10 @@ const actionsMenuCloneMonitorName = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
const CREATE_SLO = i18n.translate('xpack.synthetics.overview.actions.createSlo.name', {
|
||||
defaultMessage: 'Create SLO',
|
||||
});
|
||||
|
||||
const loadingLabel = (isEnabled: boolean) =>
|
||||
isEnabled
|
||||
? i18n.translate('xpack.synthetics.overview.actions.disablingLabel', {
|
||||
|
|
|
@ -41,6 +41,7 @@ export const SyntheticsSharedContext: React.FC<SyntheticsAppProps> = ({
|
|||
share: startPlugins.share,
|
||||
unifiedSearch: startPlugins.unifiedSearch,
|
||||
embeddable: startPlugins.embeddable,
|
||||
slo: startPlugins.slo,
|
||||
}}
|
||||
>
|
||||
<EuiThemeProvider darkMode={darkMode}>
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
EncryptedSyntheticsMonitor,
|
||||
FetchMonitorManagementListQueryArgs,
|
||||
MonitorManagementListResult,
|
||||
MonitorManagementListResultCodec,
|
||||
SyntheticsMonitor,
|
||||
MonitorFiltersResult,
|
||||
} from '../../../../../common/runtime_types';
|
||||
|
@ -44,11 +43,10 @@ export const fetchMonitorManagementList = async (
|
|||
): Promise<MonitorManagementListResult> => {
|
||||
const params = toMonitorManagementListQueryArgs(pageState);
|
||||
|
||||
return await apiService.get(
|
||||
SYNTHETICS_API_URLS.SYNTHETICS_MONITORS,
|
||||
{ ...params, version: INITIAL_REST_VERSION },
|
||||
MonitorManagementListResultCodec
|
||||
);
|
||||
return await apiService.get(SYNTHETICS_API_URLS.SYNTHETICS_MONITORS, {
|
||||
...params,
|
||||
version: INITIAL_REST_VERSION,
|
||||
});
|
||||
};
|
||||
|
||||
export const fetchDeleteMonitor = async ({ configId }: { configId: string }): Promise<void> => {
|
||||
|
|
|
@ -60,6 +60,7 @@ import { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/pu
|
|||
import type { UiActionsSetup } from '@kbn/ui-actions-plugin/public';
|
||||
import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
|
||||
import { DashboardStart, DashboardSetup } from '@kbn/dashboard-plugin/public';
|
||||
import { SloPublicStart } from '@kbn/slo-plugin/public';
|
||||
import { registerSyntheticsEmbeddables } from './apps/embeddables/register_embeddables';
|
||||
import { kibanaService } from './utils/kibana_service';
|
||||
import { PLUGIN } from '../common/constants/plugin';
|
||||
|
@ -111,6 +112,7 @@ export interface ClientPluginsStart {
|
|||
usageCollection: UsageCollectionStart;
|
||||
serverless: ServerlessPluginStart;
|
||||
licenseManagement?: LicenseManagementUIPluginSetup;
|
||||
slo?: SloPublicStart;
|
||||
presentationUtil: PresentationUtilPluginStart;
|
||||
dashboard: DashboardStart;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,9 @@ class ApiService {
|
|||
} else {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`API $s is not returning expected response, ${formatErrors(decoded.left)} for response`,
|
||||
`API ${apiUrl} is not returning expected response, ${formatErrors(
|
||||
decoded.left
|
||||
)} for response`,
|
||||
apiUrl,
|
||||
response
|
||||
);
|
||||
|
|
|
@ -97,7 +97,8 @@
|
|||
"@kbn/ui-actions-plugin",
|
||||
"@kbn/presentation-util-plugin",
|
||||
"@kbn/core-application-browser",
|
||||
"@kbn/dashboard-plugin"
|
||||
"@kbn/dashboard-plugin",
|
||||
"@kbn/slo-plugin"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue