mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] Scope APM alert creation to environment (#65681)
* adding environment to alerting * fixing translations * addressing pr comments * addressing PR comments * addressing PR comments Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
577bf0928b
commit
9a13779c4f
9 changed files with 174 additions and 53 deletions
|
@ -17,14 +17,15 @@ interface Props {
|
|||
|
||||
export function AlertingFlyout(props: Props) {
|
||||
const { addFlyoutVisible, setAddFlyoutVisibility, alertType } = props;
|
||||
|
||||
return alertType ? (
|
||||
<AlertAdd
|
||||
addFlyoutVisible={addFlyoutVisible}
|
||||
setAddFlyoutVisibility={setAddFlyoutVisibility}
|
||||
consumer="apm"
|
||||
alertTypeId={alertType}
|
||||
canChangeTrigger={false}
|
||||
/>
|
||||
) : null;
|
||||
return (
|
||||
alertType && (
|
||||
<AlertAdd
|
||||
addFlyoutVisible={addFlyoutVisible}
|
||||
setAddFlyoutVisibility={setAddFlyoutVisibility}
|
||||
consumer="apm"
|
||||
alertTypeId={alertType}
|
||||
canChangeTrigger={false}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
import { EuiSelect } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { useFetcher } from '../../../hooks/useFetcher';
|
||||
import { useLocation } from '../../../hooks/useLocation';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { history } from '../../../utils/history';
|
||||
|
@ -16,6 +15,7 @@ import {
|
|||
ENVIRONMENT_ALL,
|
||||
ENVIRONMENT_NOT_DEFINED
|
||||
} from '../../../../common/environment_filter_values';
|
||||
import { useEnvironments, ALL_OPTION } from '../../../hooks/useEnvironments';
|
||||
|
||||
function updateEnvironmentUrl(
|
||||
location: ReturnType<typeof useLocation>,
|
||||
|
@ -32,13 +32,6 @@ function updateEnvironmentUrl(
|
|||
});
|
||||
}
|
||||
|
||||
const ALL_OPTION = {
|
||||
value: ENVIRONMENT_ALL,
|
||||
text: i18n.translate('xpack.apm.filter.environment.allLabel', {
|
||||
defaultMessage: 'All'
|
||||
})
|
||||
};
|
||||
|
||||
const NOT_DEFINED_OPTION = {
|
||||
value: ENVIRONMENT_NOT_DEFINED,
|
||||
text: i18n.translate('xpack.apm.filter.environment.notDefinedLabel', {
|
||||
|
@ -74,27 +67,15 @@ function getOptions(environments: string[]) {
|
|||
|
||||
export const EnvironmentFilter: React.FC = () => {
|
||||
const location = useLocation();
|
||||
const { urlParams, uiFilters } = useUrlParams();
|
||||
const { start, end, serviceName } = urlParams;
|
||||
const { uiFilters, urlParams } = useUrlParams();
|
||||
|
||||
const { environment } = uiFilters;
|
||||
const { data: environments = [], status = 'loading' } = useFetcher(
|
||||
callApmApi => {
|
||||
if (start && end) {
|
||||
return callApmApi({
|
||||
pathname: '/api/apm/ui_filters/environments',
|
||||
params: {
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
serviceName
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
[start, end, serviceName]
|
||||
);
|
||||
const { serviceName, start, end } = urlParams;
|
||||
const { environments, status = 'loading' } = useEnvironments({
|
||||
serviceName,
|
||||
start,
|
||||
end
|
||||
});
|
||||
|
||||
return (
|
||||
<EuiSelect
|
||||
|
|
|
@ -7,15 +7,19 @@ import React from 'react';
|
|||
import { EuiFieldNumber } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isFinite } from 'lodash';
|
||||
import { EuiSelect } from '@elastic/eui';
|
||||
import { ForLastExpression } from '../../../../../triggers_actions_ui/public';
|
||||
import { ALERT_TYPES_CONFIG } from '../../../../common/alert_types';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
import { PopoverExpression } from '../ServiceAlertTrigger/PopoverExpression';
|
||||
import { useEnvironments, ALL_OPTION } from '../../../hooks/useEnvironments';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
|
||||
export interface ErrorRateAlertTriggerParams {
|
||||
windowSize: number;
|
||||
windowUnit: string;
|
||||
threshold: number;
|
||||
environment: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
|
@ -27,10 +31,15 @@ interface Props {
|
|||
export function ErrorRateAlertTrigger(props: Props) {
|
||||
const { setAlertParams, setAlertProperty, alertParams } = props;
|
||||
|
||||
const { urlParams } = useUrlParams();
|
||||
const { serviceName, start, end } = urlParams;
|
||||
const { environmentOptions } = useEnvironments({ serviceName, start, end });
|
||||
|
||||
const defaults = {
|
||||
threshold: 25,
|
||||
windowSize: 1,
|
||||
windowUnit: 'm'
|
||||
windowUnit: 'm',
|
||||
environment: ALL_OPTION.value
|
||||
};
|
||||
|
||||
const params = {
|
||||
|
@ -41,6 +50,28 @@ export function ErrorRateAlertTrigger(props: Props) {
|
|||
const threshold = isFinite(params.threshold) ? params.threshold : '';
|
||||
|
||||
const fields = [
|
||||
<PopoverExpression
|
||||
value={
|
||||
params.environment === ALL_OPTION.value
|
||||
? ALL_OPTION.text
|
||||
: params.environment
|
||||
}
|
||||
title={i18n.translate('xpack.apm.errorRateAlertTrigger.environment', {
|
||||
defaultMessage: 'Environment'
|
||||
})}
|
||||
>
|
||||
<EuiSelect
|
||||
value={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={e =>
|
||||
setAlertParams(
|
||||
'environment',
|
||||
e.target.value as ErrorRateAlertTriggerParams['environment']
|
||||
)
|
||||
}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<PopoverExpression
|
||||
title={i18n.translate('xpack.apm.errorRateAlertTrigger.isAbove', {
|
||||
defaultMessage: 'is above'
|
||||
|
|
|
@ -3,18 +3,19 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { map } from 'lodash';
|
||||
import { EuiFieldNumber, EuiSelect } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { map } from 'lodash';
|
||||
import React from 'react';
|
||||
import { ForLastExpression } from '../../../../../triggers_actions_ui/public';
|
||||
import {
|
||||
TRANSACTION_ALERT_AGGREGATION_TYPES,
|
||||
ALERT_TYPES_CONFIG
|
||||
ALERT_TYPES_CONFIG,
|
||||
TRANSACTION_ALERT_AGGREGATION_TYPES
|
||||
} from '../../../../common/alert_types';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { ALL_OPTION, useEnvironments } from '../../../hooks/useEnvironments';
|
||||
import { useServiceTransactionTypes } from '../../../hooks/useServiceTransactionTypes';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
import { PopoverExpression } from '../ServiceAlertTrigger/PopoverExpression';
|
||||
|
||||
interface Params {
|
||||
|
@ -24,6 +25,7 @@ interface Params {
|
|||
aggregationType: 'avg' | '95th' | '99th';
|
||||
serviceName: string;
|
||||
transactionType: string;
|
||||
environment: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
|
@ -39,6 +41,9 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
|
||||
const transactionTypes = useServiceTransactionTypes(urlParams);
|
||||
|
||||
const { serviceName, start, end } = urlParams;
|
||||
const { environmentOptions } = useEnvironments({ serviceName, start, end });
|
||||
|
||||
if (!transactionTypes.length) {
|
||||
return null;
|
||||
}
|
||||
|
@ -48,7 +53,8 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
aggregationType: 'avg',
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
transactionType: transactionTypes[0]
|
||||
transactionType: transactionTypes[0],
|
||||
environment: ALL_OPTION.value
|
||||
};
|
||||
|
||||
const params = {
|
||||
|
@ -57,6 +63,28 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
};
|
||||
|
||||
const fields = [
|
||||
<PopoverExpression
|
||||
value={
|
||||
params.environment === ALL_OPTION.value
|
||||
? ALL_OPTION.text
|
||||
: params.environment
|
||||
}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionDurationAlertTrigger.environment',
|
||||
{
|
||||
defaultMessage: 'Environment'
|
||||
}
|
||||
)}
|
||||
>
|
||||
<EuiSelect
|
||||
value={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={e =>
|
||||
setAlertParams('environment', e.target.value as Params['environment'])
|
||||
}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<PopoverExpression
|
||||
value={params.transactionType}
|
||||
title={i18n.translate('xpack.apm.transactionDurationAlertTrigger.type', {
|
||||
|
|
64
x-pack/plugins/apm/public/hooks/useEnvironments.tsx
Normal file
64
x-pack/plugins/apm/public/hooks/useEnvironments.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useFetcher } from './useFetcher';
|
||||
import {
|
||||
ENVIRONMENT_NOT_DEFINED,
|
||||
ENVIRONMENT_ALL
|
||||
} from '../../common/environment_filter_values';
|
||||
import { callApmApi } from '../services/rest/createCallApmApi';
|
||||
|
||||
export const ALL_OPTION = {
|
||||
value: ENVIRONMENT_ALL,
|
||||
text: i18n.translate('xpack.apm.environment.allLabel', {
|
||||
defaultMessage: 'All'
|
||||
})
|
||||
};
|
||||
|
||||
function getEnvironmentOptions(environments: string[]) {
|
||||
const environmentOptions = environments
|
||||
.filter(env => env !== ENVIRONMENT_NOT_DEFINED)
|
||||
.map(environment => ({
|
||||
value: environment,
|
||||
text: environment
|
||||
}));
|
||||
|
||||
return [ALL_OPTION, ...environmentOptions];
|
||||
}
|
||||
|
||||
export function useEnvironments({
|
||||
serviceName,
|
||||
start,
|
||||
end
|
||||
}: {
|
||||
serviceName?: string;
|
||||
start?: string;
|
||||
end?: string;
|
||||
}) {
|
||||
const { data: environments = [], status = 'loading' } = useFetcher(() => {
|
||||
if (start && end) {
|
||||
return callApmApi({
|
||||
pathname: '/api/apm/ui_filters/environments',
|
||||
params: {
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
serviceName
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, [start, end, serviceName]);
|
||||
|
||||
const environmentOptions = useMemo(
|
||||
() => getEnvironmentOptions(environments),
|
||||
[environments]
|
||||
);
|
||||
|
||||
return { environments, status, environmentOptions };
|
||||
}
|
|
@ -8,6 +8,7 @@ import { schema, TypeOf } from '@kbn/config-schema';
|
|||
import { Observable } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import {
|
||||
ESSearchResponse,
|
||||
|
@ -15,7 +16,8 @@ import {
|
|||
} from '../../../typings/elasticsearch';
|
||||
import {
|
||||
PROCESSOR_EVENT,
|
||||
SERVICE_NAME
|
||||
SERVICE_NAME,
|
||||
SERVICE_ENVIRONMENT
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { AlertingPlugin } from '../../../../alerting/server';
|
||||
import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
|
||||
|
@ -30,7 +32,8 @@ const paramsSchema = schema.object({
|
|||
serviceName: schema.string(),
|
||||
windowSize: schema.number(),
|
||||
windowUnit: schema.string(),
|
||||
threshold: schema.number()
|
||||
threshold: schema.number(),
|
||||
environment: schema.string()
|
||||
});
|
||||
|
||||
const alertTypeConfig = ALERT_TYPES_CONFIG[AlertType.ErrorRate];
|
||||
|
@ -71,6 +74,11 @@ export function registerErrorRateAlertType({
|
|||
savedObjectsClient: services.savedObjectsClient
|
||||
});
|
||||
|
||||
const environmentTerm =
|
||||
alertParams.environment === ENVIRONMENT_ALL
|
||||
? []
|
||||
: [{ term: { [SERVICE_ENVIRONMENT]: alertParams.environment } }];
|
||||
|
||||
const searchParams = {
|
||||
index: indices['apm_oss.errorIndices'],
|
||||
size: 0,
|
||||
|
@ -94,7 +102,8 @@ export function registerErrorRateAlertType({
|
|||
term: {
|
||||
[SERVICE_NAME]: alertParams.serviceName
|
||||
}
|
||||
}
|
||||
},
|
||||
...environmentTerm
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -8,13 +8,15 @@ import { schema, TypeOf } from '@kbn/config-schema';
|
|||
import { Observable } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import { ESSearchResponse } from '../../../typings/elasticsearch';
|
||||
import {
|
||||
PROCESSOR_EVENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_DURATION
|
||||
TRANSACTION_DURATION,
|
||||
SERVICE_ENVIRONMENT
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { AlertingPlugin } from '../../../../alerting/server';
|
||||
import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
|
||||
|
@ -35,7 +37,8 @@ const paramsSchema = schema.object({
|
|||
schema.literal('avg'),
|
||||
schema.literal('95th'),
|
||||
schema.literal('99th')
|
||||
])
|
||||
]),
|
||||
environment: schema.string()
|
||||
});
|
||||
|
||||
const alertTypeConfig = ALERT_TYPES_CONFIG[AlertType.TransactionDuration];
|
||||
|
@ -85,6 +88,11 @@ export function registerTransactionDurationAlertType({
|
|||
savedObjectsClient: services.savedObjectsClient
|
||||
});
|
||||
|
||||
const environmentTerm =
|
||||
alertParams.environment === ENVIRONMENT_ALL
|
||||
? []
|
||||
: [{ term: { [SERVICE_ENVIRONMENT]: alertParams.environment } }];
|
||||
|
||||
const searchParams = {
|
||||
index: indices['apm_oss.transactionIndices'],
|
||||
size: 0,
|
||||
|
@ -113,7 +121,8 @@ export function registerTransactionDurationAlertType({
|
|||
term: {
|
||||
[TRANSACTION_TYPE]: alertParams.transactionType
|
||||
}
|
||||
}
|
||||
},
|
||||
...environmentTerm
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4214,7 +4214,6 @@
|
|||
"xpack.apm.fetcher.error.status": "エラー",
|
||||
"xpack.apm.fetcher.error.title": "リソースの取得中にエラーが発生しました",
|
||||
"xpack.apm.fetcher.error.url": "URL",
|
||||
"xpack.apm.filter.environment.allLabel": "すべて",
|
||||
"xpack.apm.filter.environment.label": "環境",
|
||||
"xpack.apm.filter.environment.notDefinedLabel": "未定義",
|
||||
"xpack.apm.filter.environment.selectEnvironmentLabel": "環境を選択",
|
||||
|
|
|
@ -4215,7 +4215,6 @@
|
|||
"xpack.apm.fetcher.error.status": "错误",
|
||||
"xpack.apm.fetcher.error.title": "提取资源时出错",
|
||||
"xpack.apm.fetcher.error.url": "URL",
|
||||
"xpack.apm.filter.environment.allLabel": "全部",
|
||||
"xpack.apm.filter.environment.label": "环境",
|
||||
"xpack.apm.filter.environment.notDefinedLabel": "未定义",
|
||||
"xpack.apm.filter.environment.selectEnvironmentLabel": "选择环境",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue