[APM] Add transaction error rate alert (#76933)
This commit is contained in:
parent
becb137835
commit
fb6292965b
|
@ -7,42 +7,33 @@
|
|||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export enum AlertType {
|
||||
ErrorRate = 'apm.error_rate',
|
||||
ErrorCount = 'apm.error_rate', // ErrorRate was renamed to ErrorCount but the key is kept as `error_rate` for backwards-compat.
|
||||
TransactionErrorRate = 'apm.transaction_error_rate',
|
||||
TransactionDuration = 'apm.transaction_duration',
|
||||
TransactionDurationAnomaly = 'apm.transaction_duration_anomaly',
|
||||
}
|
||||
|
||||
const THRESHOLD_MET_GROUP = {
|
||||
id: 'threshold_met',
|
||||
name: i18n.translate('xpack.apm.a.thresholdMet', {
|
||||
defaultMessage: 'Threshold met',
|
||||
}),
|
||||
};
|
||||
|
||||
export const ALERT_TYPES_CONFIG = {
|
||||
[AlertType.ErrorRate]: {
|
||||
name: i18n.translate('xpack.apm.errorRateAlert.name', {
|
||||
defaultMessage: 'Error rate',
|
||||
[AlertType.ErrorCount]: {
|
||||
name: i18n.translate('xpack.apm.errorCountAlert.name', {
|
||||
defaultMessage: 'Error count threshold',
|
||||
}),
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'threshold_met',
|
||||
name: i18n.translate('xpack.apm.errorRateAlert.thresholdMet', {
|
||||
defaultMessage: 'Threshold met',
|
||||
}),
|
||||
},
|
||||
],
|
||||
actionGroups: [THRESHOLD_MET_GROUP],
|
||||
defaultActionGroupId: 'threshold_met',
|
||||
producer: 'apm',
|
||||
},
|
||||
[AlertType.TransactionDuration]: {
|
||||
name: i18n.translate('xpack.apm.transactionDurationAlert.name', {
|
||||
defaultMessage: 'Transaction duration',
|
||||
defaultMessage: 'Transaction duration threshold',
|
||||
}),
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'threshold_met',
|
||||
name: i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.thresholdMet',
|
||||
{
|
||||
defaultMessage: 'Threshold met',
|
||||
}
|
||||
),
|
||||
},
|
||||
],
|
||||
actionGroups: [THRESHOLD_MET_GROUP],
|
||||
defaultActionGroupId: 'threshold_met',
|
||||
producer: 'apm',
|
||||
},
|
||||
|
@ -50,39 +41,24 @@ export const ALERT_TYPES_CONFIG = {
|
|||
name: i18n.translate('xpack.apm.transactionDurationAnomalyAlert.name', {
|
||||
defaultMessage: 'Transaction duration anomaly',
|
||||
}),
|
||||
actionGroups: [
|
||||
{
|
||||
id: 'threshold_met',
|
||||
name: i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.thresholdMet',
|
||||
{
|
||||
defaultMessage: 'Threshold met',
|
||||
}
|
||||
),
|
||||
},
|
||||
],
|
||||
actionGroups: [THRESHOLD_MET_GROUP],
|
||||
defaultActionGroupId: 'threshold_met',
|
||||
producer: 'apm',
|
||||
},
|
||||
[AlertType.TransactionErrorRate]: {
|
||||
name: i18n.translate('xpack.apm.transactionErrorRateAlert.name', {
|
||||
defaultMessage: 'Transaction error rate threshold',
|
||||
}),
|
||||
actionGroups: [THRESHOLD_MET_GROUP],
|
||||
defaultActionGroupId: 'threshold_met',
|
||||
producer: 'apm',
|
||||
},
|
||||
};
|
||||
|
||||
export const TRANSACTION_ALERT_AGGREGATION_TYPES = {
|
||||
avg: i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.avg',
|
||||
{
|
||||
defaultMessage: 'Average',
|
||||
}
|
||||
),
|
||||
'95th': i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.95th',
|
||||
{
|
||||
defaultMessage: '95th percentile',
|
||||
}
|
||||
),
|
||||
'99th': i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.99th',
|
||||
{
|
||||
defaultMessage: '99th percentile',
|
||||
}
|
||||
),
|
||||
};
|
||||
// Server side registrations
|
||||
// x-pack/plugins/apm/server/lib/alerts/<alert>.ts
|
||||
// x-pack/plugins/apm/server/lib/alerts/register_apm_alerts.ts
|
||||
|
||||
// Client side registrations:
|
||||
// x-pack/plugins/apm/public/components/alerting/<alert>/index.tsx
|
||||
// x-pack/plugins/apm/public/components/alerting/register_apm_alerts
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
|
||||
import { storiesOf } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { ErrorRateAlertTrigger } from '.';
|
||||
import { ErrorCountAlertTrigger } from '.';
|
||||
import { ApmPluginContextValue } from '../../../context/ApmPluginContext';
|
||||
import {
|
||||
mockApmPluginContextValue,
|
||||
MockApmPluginContextWrapper,
|
||||
} from '../../../context/ApmPluginContext/MockApmPluginContext';
|
||||
|
||||
storiesOf('app/ErrorRateAlertTrigger', module).add(
|
||||
storiesOf('app/ErrorCountAlertTrigger', module).add(
|
||||
'example',
|
||||
() => {
|
||||
const params = {
|
||||
|
@ -26,7 +26,7 @@ storiesOf('app/ErrorRateAlertTrigger', module).add(
|
|||
value={(mockApmPluginContextValue as unknown) as ApmPluginContextValue}
|
||||
>
|
||||
<div style={{ width: 400 }}>
|
||||
<ErrorRateAlertTrigger
|
||||
<ErrorCountAlertTrigger
|
||||
alertParams={params as any}
|
||||
setAlertParams={() => undefined}
|
||||
setAlertProperty={() => undefined}
|
||||
|
@ -37,7 +37,7 @@ storiesOf('app/ErrorRateAlertTrigger', module).add(
|
|||
},
|
||||
{
|
||||
info: {
|
||||
propTablesExclude: [ErrorRateAlertTrigger, MockApmPluginContextWrapper],
|
||||
propTablesExclude: [ErrorCountAlertTrigger, MockApmPluginContextWrapper],
|
||||
source: false,
|
||||
},
|
||||
}
|
|
@ -3,36 +3,33 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { EuiFieldNumber, EuiSelect } from '@elastic/eui';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { isFinite } from 'lodash';
|
||||
import React from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { ForLastExpression } from '../../../../../triggers_actions_ui/public';
|
||||
import { ALERT_TYPES_CONFIG } from '../../../../common/alert_types';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
getEnvironmentLabel,
|
||||
} from '../../../../common/environment_filter_values';
|
||||
import { ALERT_TYPES_CONFIG, AlertType } from '../../../../common/alert_types';
|
||||
import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
|
||||
import { useEnvironments } from '../../../hooks/useEnvironments';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { EnvironmentField, ServiceField, IsAboveField } from '../fields';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
import { PopoverExpression } from '../ServiceAlertTrigger/PopoverExpression';
|
||||
|
||||
export interface ErrorRateAlertTriggerParams {
|
||||
export interface AlertParams {
|
||||
windowSize: number;
|
||||
windowUnit: string;
|
||||
threshold: number;
|
||||
serviceName: string;
|
||||
environment: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
alertParams: ErrorRateAlertTriggerParams;
|
||||
alertParams: AlertParams;
|
||||
setAlertParams: (key: string, value: any) => void;
|
||||
setAlertProperty: (key: string, value: any) => void;
|
||||
}
|
||||
|
||||
export function ErrorRateAlertTrigger(props: Props) {
|
||||
export function ErrorCountAlertTrigger(props: Props) {
|
||||
const { setAlertParams, setAlertProperty, alertParams } = props;
|
||||
const { serviceName } = useParams<{ serviceName?: string }>();
|
||||
const { urlParams } = useUrlParams();
|
||||
|
@ -51,45 +48,20 @@ export function ErrorRateAlertTrigger(props: Props) {
|
|||
...alertParams,
|
||||
};
|
||||
|
||||
const threshold = isFinite(params.threshold) ? params.threshold : '';
|
||||
|
||||
const fields = [
|
||||
<PopoverExpression
|
||||
value={getEnvironmentLabel(params.environment)}
|
||||
title={i18n.translate('xpack.apm.errorRateAlertTrigger.environment', {
|
||||
defaultMessage: 'Environment',
|
||||
<ServiceField value={serviceName} />,
|
||||
<EnvironmentField
|
||||
currentValue={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={(e) => setAlertParams('environment', e.target.value)}
|
||||
/>,
|
||||
<IsAboveField
|
||||
value={params.threshold}
|
||||
unit={i18n.translate('xpack.apm.errorCountAlertTrigger.errors', {
|
||||
defaultMessage: ' errors',
|
||||
})}
|
||||
>
|
||||
<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',
|
||||
})}
|
||||
value={threshold.toString()}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
value={threshold}
|
||||
step={0}
|
||||
onChange={(e) =>
|
||||
setAlertParams('threshold', parseInt(e.target.value, 10))
|
||||
}
|
||||
compressed
|
||||
append={i18n.translate('xpack.apm.errorRateAlertTrigger.errors', {
|
||||
defaultMessage: 'errors',
|
||||
})}
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
onChange={(value) => setAlertParams('threshold', value)}
|
||||
/>,
|
||||
<ForLastExpression
|
||||
onChangeWindowSize={(windowSize) =>
|
||||
setAlertParams('windowSize', windowSize || '')
|
||||
|
@ -108,7 +80,7 @@ export function ErrorRateAlertTrigger(props: Props) {
|
|||
|
||||
return (
|
||||
<ServiceAlertTrigger
|
||||
alertTypeName={ALERT_TYPES_CONFIG['apm.error_rate'].name}
|
||||
alertTypeName={ALERT_TYPES_CONFIG[AlertType.ErrorCount].name}
|
||||
defaults={defaults}
|
||||
fields={fields}
|
||||
setAlertParams={setAlertParams}
|
||||
|
@ -120,4 +92,4 @@ export function ErrorRateAlertTrigger(props: Props) {
|
|||
// Default export is required for React.lazy loading
|
||||
//
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default ErrorRateAlertTrigger;
|
||||
export default ErrorCountAlertTrigger;
|
|
@ -15,7 +15,6 @@ interface Props {
|
|||
|
||||
export function PopoverExpression(props: Props) {
|
||||
const { title, value, children } = props;
|
||||
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
|
||||
return (
|
|
@ -3,26 +3,27 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { EuiFieldNumber, EuiSelect } from '@elastic/eui';
|
||||
import { EuiSelect } from '@elastic/eui';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { map } from 'lodash';
|
||||
import React from 'react';
|
||||
import { ForLastExpression } from '../../../../../triggers_actions_ui/public';
|
||||
import {
|
||||
ALERT_TYPES_CONFIG,
|
||||
TRANSACTION_ALERT_AGGREGATION_TYPES,
|
||||
} from '../../../../common/alert_types';
|
||||
import { ALERT_TYPES_CONFIG } from '../../../../common/alert_types';
|
||||
import { useEnvironments } from '../../../hooks/useEnvironments';
|
||||
import { useServiceTransactionTypes } from '../../../hooks/useServiceTransactionTypes';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
import { PopoverExpression } from '../ServiceAlertTrigger/PopoverExpression';
|
||||
import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
getEnvironmentLabel,
|
||||
} from '../../../../common/environment_filter_values';
|
||||
EnvironmentField,
|
||||
ServiceField,
|
||||
TransactionTypeField,
|
||||
IsAboveField,
|
||||
} from '../fields';
|
||||
|
||||
interface Params {
|
||||
interface AlertParams {
|
||||
windowSize: number;
|
||||
windowUnit: string;
|
||||
threshold: number;
|
||||
|
@ -32,23 +33,42 @@ interface Params {
|
|||
environment: string;
|
||||
}
|
||||
|
||||
const TRANSACTION_ALERT_AGGREGATION_TYPES = {
|
||||
avg: i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.avg',
|
||||
{
|
||||
defaultMessage: 'Average',
|
||||
}
|
||||
),
|
||||
'95th': i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.95th',
|
||||
{
|
||||
defaultMessage: '95th percentile',
|
||||
}
|
||||
),
|
||||
'99th': i18n.translate(
|
||||
'xpack.apm.transactionDurationAlert.aggregationType.99th',
|
||||
{
|
||||
defaultMessage: '99th percentile',
|
||||
}
|
||||
),
|
||||
};
|
||||
|
||||
interface Props {
|
||||
alertParams: Params;
|
||||
alertParams: AlertParams;
|
||||
setAlertParams: (key: string, value: any) => void;
|
||||
setAlertProperty: (key: string, value: any) => void;
|
||||
}
|
||||
|
||||
export function TransactionDurationAlertTrigger(props: Props) {
|
||||
const { setAlertParams, alertParams, setAlertProperty } = props;
|
||||
const { serviceName } = alertParams;
|
||||
const { urlParams } = useUrlParams();
|
||||
|
||||
const transactionTypes = useServiceTransactionTypes(urlParams);
|
||||
|
||||
const { start, end } = urlParams;
|
||||
const { serviceName } = useParams<{ serviceName?: string }>();
|
||||
const { start, end, transactionType } = urlParams;
|
||||
const { environmentOptions } = useEnvironments({ serviceName, start, end });
|
||||
|
||||
if (!transactionTypes.length) {
|
||||
if (!transactionTypes.length || !serviceName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -57,7 +77,9 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
aggregationType: 'avg',
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
transactionType: transactionTypes[0],
|
||||
|
||||
// use the current transaction type or default to the first in the list
|
||||
transactionType: transactionType || transactionTypes[0],
|
||||
environment: urlParams.environment || ENVIRONMENT_ALL.value,
|
||||
};
|
||||
|
||||
|
@ -67,47 +89,17 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
};
|
||||
|
||||
const fields = [
|
||||
<PopoverExpression
|
||||
value={getEnvironmentLabel(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', {
|
||||
defaultMessage: 'Type',
|
||||
})}
|
||||
>
|
||||
<EuiSelect
|
||||
value={params.transactionType}
|
||||
options={transactionTypes.map((key) => {
|
||||
return {
|
||||
text: key,
|
||||
value: key,
|
||||
};
|
||||
})}
|
||||
onChange={(e) =>
|
||||
setAlertParams(
|
||||
'transactionType',
|
||||
e.target.value as Params['transactionType']
|
||||
)
|
||||
}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<ServiceField value={serviceName} />,
|
||||
<EnvironmentField
|
||||
currentValue={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={(e) => setAlertParams('environment', e.target.value)}
|
||||
/>,
|
||||
<TransactionTypeField
|
||||
currentValue={params.transactionType}
|
||||
options={transactionTypes.map((key) => ({ text: key, value: key }))}
|
||||
onChange={(e) => setAlertParams('transactionType', e.target.value)}
|
||||
/>,
|
||||
<PopoverExpression
|
||||
value={params.aggregationType}
|
||||
title={i18n.translate('xpack.apm.transactionDurationAlertTrigger.when', {
|
||||
|
@ -122,33 +114,17 @@ export function TransactionDurationAlertTrigger(props: Props) {
|
|||
value: key,
|
||||
};
|
||||
})}
|
||||
onChange={(e) =>
|
||||
setAlertParams(
|
||||
'aggregationType',
|
||||
e.target.value as Params['aggregationType']
|
||||
)
|
||||
}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<PopoverExpression
|
||||
value={params.threshold ? `${params.threshold}ms` : ''}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionDurationAlertTrigger.isAbove',
|
||||
{
|
||||
defaultMessage: 'is above',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
value={params.threshold ?? ''}
|
||||
onChange={(e) => setAlertParams('threshold', e.target.value)}
|
||||
append={i18n.translate('xpack.apm.transactionDurationAlertTrigger.ms', {
|
||||
defaultMessage: 'ms',
|
||||
})}
|
||||
onChange={(e) => setAlertParams('aggregationType', e.target.value)}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<IsAboveField
|
||||
value={params.threshold}
|
||||
unit={i18n.translate('xpack.apm.transactionDurationAlertTrigger.ms', {
|
||||
defaultMessage: 'ms',
|
||||
})}
|
||||
onChange={(value) => setAlertParams('threshold', value)}
|
||||
/>,
|
||||
<ForLastExpression
|
||||
onChangeWindowSize={(timeWindowSize) =>
|
||||
setAlertParams('windowSize', timeWindowSize || '')
|
|
@ -3,7 +3,8 @@
|
|||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { EuiExpression, EuiSelect } from '@elastic/eui';
|
||||
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { ALERT_TYPES_CONFIG } from '../../../../common/alert_types';
|
||||
|
@ -16,14 +17,16 @@ import {
|
|||
AnomalySeverity,
|
||||
SelectAnomalySeverity,
|
||||
} from './SelectAnomalySeverity';
|
||||
import {
|
||||
ENVIRONMENT_ALL,
|
||||
getEnvironmentLabel,
|
||||
} from '../../../../common/environment_filter_values';
|
||||
import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
|
||||
import {
|
||||
TRANSACTION_PAGE_LOAD,
|
||||
TRANSACTION_REQUEST,
|
||||
} from '../../../../common/transaction_types';
|
||||
import {
|
||||
EnvironmentField,
|
||||
ServiceField,
|
||||
TransactionTypeField,
|
||||
} from '../fields';
|
||||
|
||||
interface Params {
|
||||
windowSize: number;
|
||||
|
@ -42,9 +45,9 @@ interface Props {
|
|||
|
||||
export function TransactionDurationAnomalyAlertTrigger(props: Props) {
|
||||
const { setAlertParams, alertParams, setAlertProperty } = props;
|
||||
const { serviceName } = alertParams;
|
||||
const { urlParams } = useUrlParams();
|
||||
const transactionTypes = useServiceTransactionTypes(urlParams);
|
||||
const { serviceName } = useParams<{ serviceName?: string }>();
|
||||
const { start, end } = urlParams;
|
||||
const { environmentOptions } = useEnvironments({ serviceName, start, end });
|
||||
const supportedTransactionTypes = transactionTypes.filter((transactionType) =>
|
||||
|
@ -55,10 +58,13 @@ export function TransactionDurationAnomalyAlertTrigger(props: Props) {
|
|||
return null;
|
||||
}
|
||||
|
||||
// 'page-load' for RUM, 'request' otherwise
|
||||
const transactionType = supportedTransactionTypes[0];
|
||||
|
||||
const defaults: Params = {
|
||||
windowSize: 15,
|
||||
windowUnit: 'm',
|
||||
transactionType: supportedTransactionTypes[0], // 'page-load' for RUM, 'request' otherwise
|
||||
transactionType,
|
||||
serviceName,
|
||||
environment: urlParams.environment || ENVIRONMENT_ALL.value,
|
||||
anomalyScore: 75,
|
||||
|
@ -70,31 +76,13 @@ export function TransactionDurationAnomalyAlertTrigger(props: Props) {
|
|||
};
|
||||
|
||||
const fields = [
|
||||
<EuiExpression
|
||||
description={i18n.translate(
|
||||
'xpack.apm.transactionDurationAnomalyAlertTrigger.service',
|
||||
{
|
||||
defaultMessage: 'Service',
|
||||
}
|
||||
)}
|
||||
value={serviceName}
|
||||
<ServiceField value={serviceName} />,
|
||||
<TransactionTypeField currentValue={transactionType} />,
|
||||
<EnvironmentField
|
||||
currentValue={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={(e) => setAlertParams('environment', e.target.value)}
|
||||
/>,
|
||||
<PopoverExpression
|
||||
value={getEnvironmentLabel(params.environment)}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionDurationAnomalyAlertTrigger.environment',
|
||||
{
|
||||
defaultMessage: 'Environment',
|
||||
}
|
||||
)}
|
||||
>
|
||||
<EuiSelect
|
||||
value={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={(e) => setAlertParams('environment', e.target.value)}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>,
|
||||
<PopoverExpression
|
||||
value={<AnomalySeverity severityScore={params.anomalyScore} />}
|
||||
title={i18n.translate(
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 { useParams } from 'react-router-dom';
|
||||
import React from 'react';
|
||||
import { ForLastExpression } from '../../../../../triggers_actions_ui/public';
|
||||
import { ALERT_TYPES_CONFIG, AlertType } from '../../../../common/alert_types';
|
||||
import { useEnvironments } from '../../../hooks/useEnvironments';
|
||||
import { useServiceTransactionTypes } from '../../../hooks/useServiceTransactionTypes';
|
||||
import { useUrlParams } from '../../../hooks/useUrlParams';
|
||||
import { ServiceAlertTrigger } from '../ServiceAlertTrigger';
|
||||
|
||||
import { ENVIRONMENT_ALL } from '../../../../common/environment_filter_values';
|
||||
import {
|
||||
ServiceField,
|
||||
TransactionTypeField,
|
||||
EnvironmentField,
|
||||
IsAboveField,
|
||||
} from '../fields';
|
||||
|
||||
interface AlertParams {
|
||||
windowSize: number;
|
||||
windowUnit: string;
|
||||
threshold: number;
|
||||
serviceName: string;
|
||||
transactionType: string;
|
||||
environment: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
alertParams: AlertParams;
|
||||
setAlertParams: (key: string, value: any) => void;
|
||||
setAlertProperty: (key: string, value: any) => void;
|
||||
}
|
||||
|
||||
export function TransactionErrorRateAlertTrigger(props: Props) {
|
||||
const { setAlertParams, alertParams, setAlertProperty } = props;
|
||||
const { urlParams } = useUrlParams();
|
||||
const transactionTypes = useServiceTransactionTypes(urlParams);
|
||||
const { serviceName } = useParams<{ serviceName?: string }>();
|
||||
const { start, end, transactionType } = urlParams;
|
||||
const { environmentOptions } = useEnvironments({ serviceName, start, end });
|
||||
|
||||
if (!transactionTypes.length || !serviceName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const defaultParams = {
|
||||
threshold: 30,
|
||||
windowSize: 5,
|
||||
windowUnit: 'm',
|
||||
transactionType: transactionType || transactionTypes[0],
|
||||
environment: urlParams.environment || ENVIRONMENT_ALL.value,
|
||||
};
|
||||
|
||||
const params = {
|
||||
...defaultParams,
|
||||
...alertParams,
|
||||
};
|
||||
|
||||
const fields = [
|
||||
<ServiceField value={serviceName} />,
|
||||
<EnvironmentField
|
||||
currentValue={params.environment}
|
||||
options={environmentOptions}
|
||||
onChange={(e) => setAlertParams('environment', e.target.value)}
|
||||
/>,
|
||||
<TransactionTypeField
|
||||
currentValue={params.transactionType}
|
||||
options={transactionTypes.map((key) => ({ text: key, value: key }))}
|
||||
onChange={(e) => setAlertParams('transactionType', e.target.value)}
|
||||
/>,
|
||||
<IsAboveField
|
||||
value={params.threshold}
|
||||
unit="%"
|
||||
onChange={(value) => setAlertParams('threshold', value)}
|
||||
/>,
|
||||
<ForLastExpression
|
||||
onChangeWindowSize={(timeWindowSize) =>
|
||||
setAlertParams('windowSize', timeWindowSize || '')
|
||||
}
|
||||
onChangeWindowUnit={(timeWindowUnit) =>
|
||||
setAlertParams('windowUnit', timeWindowUnit)
|
||||
}
|
||||
timeWindowSize={params.windowSize}
|
||||
timeWindowUnit={params.windowUnit}
|
||||
errors={{
|
||||
timeWindowSize: [],
|
||||
timeWindowUnit: [],
|
||||
}}
|
||||
/>,
|
||||
];
|
||||
|
||||
return (
|
||||
<ServiceAlertTrigger
|
||||
alertTypeName={ALERT_TYPES_CONFIG[AlertType.TransactionErrorRate].name}
|
||||
fields={fields}
|
||||
defaults={defaultParams}
|
||||
setAlertParams={setAlertParams}
|
||||
setAlertProperty={setAlertProperty}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Default export is required for React.lazy loading
|
||||
//
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default TransactionErrorRateAlertTrigger;
|
108
x-pack/plugins/apm/public/components/alerting/fields.tsx
Normal file
108
x-pack/plugins/apm/public/components/alerting/fields.tsx
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* 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 { EuiSelect, EuiExpression, EuiFieldNumber } from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiSelectOption } from '@elastic/eui';
|
||||
import { getEnvironmentLabel } from '../../../common/environment_filter_values';
|
||||
import { PopoverExpression } from './ServiceAlertTrigger/PopoverExpression';
|
||||
|
||||
export function ServiceField({ value }: { value?: string }) {
|
||||
return (
|
||||
<EuiExpression
|
||||
description={i18n.translate('xpack.apm.alerting.fields.service', {
|
||||
defaultMessage: 'Service',
|
||||
})}
|
||||
value={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function EnvironmentField({
|
||||
currentValue,
|
||||
options,
|
||||
onChange,
|
||||
}: {
|
||||
currentValue: string;
|
||||
options: EuiSelectOption[];
|
||||
onChange: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
}) {
|
||||
return (
|
||||
<PopoverExpression
|
||||
value={getEnvironmentLabel(currentValue)}
|
||||
title={i18n.translate('xpack.apm.alerting.fields.environment', {
|
||||
defaultMessage: 'Environment',
|
||||
})}
|
||||
>
|
||||
<EuiSelect
|
||||
value={currentValue}
|
||||
options={options}
|
||||
onChange={onChange}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>
|
||||
);
|
||||
}
|
||||
|
||||
export function TransactionTypeField({
|
||||
currentValue,
|
||||
options,
|
||||
onChange,
|
||||
}: {
|
||||
currentValue: string;
|
||||
options?: EuiSelectOption[];
|
||||
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
||||
}) {
|
||||
const label = i18n.translate('xpack.apm.alerting.fields.type', {
|
||||
defaultMessage: 'Type',
|
||||
});
|
||||
|
||||
if (!options || options.length === 1) {
|
||||
return <EuiExpression description={label} value={currentValue} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<PopoverExpression value={currentValue} title={label}>
|
||||
<EuiSelect
|
||||
value={currentValue}
|
||||
options={options}
|
||||
onChange={onChange}
|
||||
compressed
|
||||
/>
|
||||
</PopoverExpression>
|
||||
);
|
||||
}
|
||||
|
||||
export function IsAboveField({
|
||||
value,
|
||||
unit,
|
||||
onChange,
|
||||
step,
|
||||
}: {
|
||||
value: number;
|
||||
unit: string;
|
||||
onChange: (value: number) => void;
|
||||
step?: number;
|
||||
}) {
|
||||
return (
|
||||
<PopoverExpression
|
||||
value={value ? `${value.toString()}${unit}` : ''}
|
||||
title={i18n.translate(
|
||||
'xpack.apm.transactionErrorRateAlertTrigger.isAbove',
|
||||
{ defaultMessage: 'is above' }
|
||||
)}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
value={value ?? ''}
|
||||
onChange={(e) => onChange(parseInt(e.target.value, 10))}
|
||||
append={unit}
|
||||
compressed
|
||||
step={step}
|
||||
/>
|
||||
</PopoverExpression>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
import { lazy } from 'react';
|
||||
import { AlertType } from '../../../common/alert_types';
|
||||
import { ApmPluginStartDeps } from '../../plugin';
|
||||
|
||||
export function registerApmAlerts(
|
||||
alertTypeRegistry: ApmPluginStartDeps['triggers_actions_ui']['alertTypeRegistry']
|
||||
) {
|
||||
alertTypeRegistry.register({
|
||||
id: AlertType.ErrorCount,
|
||||
name: i18n.translate('xpack.apm.alertTypes.errorCount', {
|
||||
defaultMessage: 'Error count threshold',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(() => import('./ErrorCountAlertTrigger')),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
|
||||
alertTypeRegistry.register({
|
||||
id: AlertType.TransactionDuration,
|
||||
name: i18n.translate('xpack.apm.alertTypes.transactionDuration', {
|
||||
defaultMessage: 'Transaction duration threshold',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() => import('./TransactionDurationAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
|
||||
alertTypeRegistry.register({
|
||||
id: AlertType.TransactionErrorRate,
|
||||
name: i18n.translate('xpack.apm.alertTypes.transactionErrorRate', {
|
||||
defaultMessage: 'Transaction error rate threshold',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() => import('./TransactionErrorRateAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
|
||||
alertTypeRegistry.register({
|
||||
id: AlertType.TransactionDurationAnomaly,
|
||||
name: i18n.translate('xpack.apm.alertTypes.transactionDurationAnomaly', {
|
||||
defaultMessage: 'Transaction duration anomaly',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() => import('./TransactionDurationAnomalyAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
}
|
|
@ -24,9 +24,13 @@ const transactionDurationLabel = i18n.translate(
|
|||
'xpack.apm.serviceDetails.alertsMenu.transactionDuration',
|
||||
{ defaultMessage: 'Transaction duration' }
|
||||
);
|
||||
const errorRateLabel = i18n.translate(
|
||||
'xpack.apm.serviceDetails.alertsMenu.errorRate',
|
||||
{ defaultMessage: 'Error rate' }
|
||||
const transactionErrorRateLabel = i18n.translate(
|
||||
'xpack.apm.serviceDetails.alertsMenu.transactionErrorRate',
|
||||
{ defaultMessage: 'Transaction error rate' }
|
||||
);
|
||||
const errorCountLabel = i18n.translate(
|
||||
'xpack.apm.serviceDetails.alertsMenu.errorCount',
|
||||
{ defaultMessage: 'Error count' }
|
||||
);
|
||||
const createThresholdAlertLabel = i18n.translate(
|
||||
'xpack.apm.serviceDetails.alertsMenu.createThresholdAlert',
|
||||
|
@ -38,8 +42,10 @@ const createAnomalyAlertAlertLabel = i18n.translate(
|
|||
);
|
||||
|
||||
const CREATE_TRANSACTION_DURATION_ALERT_PANEL_ID =
|
||||
'create_transaction_duration';
|
||||
const CREATE_ERROR_RATE_ALERT_PANEL_ID = 'create_error_rate';
|
||||
'create_transaction_duration_panel';
|
||||
const CREATE_TRANSACTION_ERROR_RATE_ALERT_PANEL_ID =
|
||||
'create_transaction_error_rate_panel';
|
||||
const CREATE_ERROR_COUNT_ALERT_PANEL_ID = 'create_error_count_panel';
|
||||
|
||||
interface Props {
|
||||
canReadAlerts: boolean;
|
||||
|
@ -77,7 +83,14 @@ export function AlertIntegrations(props: Props) {
|
|||
name: transactionDurationLabel,
|
||||
panel: CREATE_TRANSACTION_DURATION_ALERT_PANEL_ID,
|
||||
},
|
||||
{ name: errorRateLabel, panel: CREATE_ERROR_RATE_ALERT_PANEL_ID },
|
||||
{
|
||||
name: transactionErrorRateLabel,
|
||||
panel: CREATE_TRANSACTION_ERROR_RATE_ALERT_PANEL_ID,
|
||||
},
|
||||
{
|
||||
name: errorCountLabel,
|
||||
panel: CREATE_ERROR_COUNT_ALERT_PANEL_ID,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...(canReadAlerts
|
||||
|
@ -96,10 +109,13 @@ export function AlertIntegrations(props: Props) {
|
|||
: []),
|
||||
],
|
||||
},
|
||||
|
||||
// transaction duration panel
|
||||
{
|
||||
id: CREATE_TRANSACTION_DURATION_ALERT_PANEL_ID,
|
||||
title: transactionDurationLabel,
|
||||
items: [
|
||||
// threshold alerts
|
||||
{
|
||||
name: createThresholdAlertLabel,
|
||||
onClick: () => {
|
||||
|
@ -107,6 +123,8 @@ export function AlertIntegrations(props: Props) {
|
|||
setPopoverOpen(false);
|
||||
},
|
||||
},
|
||||
|
||||
// anomaly alerts
|
||||
...(canReadAnomalies
|
||||
? [
|
||||
{
|
||||
|
@ -120,14 +138,32 @@ export function AlertIntegrations(props: Props) {
|
|||
: []),
|
||||
],
|
||||
},
|
||||
|
||||
// transaction error rate panel
|
||||
{
|
||||
id: CREATE_ERROR_RATE_ALERT_PANEL_ID,
|
||||
title: errorRateLabel,
|
||||
id: CREATE_TRANSACTION_ERROR_RATE_ALERT_PANEL_ID,
|
||||
title: transactionErrorRateLabel,
|
||||
items: [
|
||||
// threshold alerts
|
||||
{
|
||||
name: createThresholdAlertLabel,
|
||||
onClick: () => {
|
||||
setAlertType(AlertType.TransactionErrorRate);
|
||||
setPopoverOpen(false);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// error alerts panel
|
||||
{
|
||||
id: CREATE_ERROR_COUNT_ALERT_PANEL_ID,
|
||||
title: errorCountLabel,
|
||||
items: [
|
||||
{
|
||||
name: createThresholdAlertLabel,
|
||||
onClick: () => {
|
||||
setAlertType(AlertType.ErrorRate);
|
||||
setAlertType(AlertType.ErrorCount);
|
||||
setPopoverOpen(false);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { lazy } from 'react';
|
||||
import { ConfigSchema } from '.';
|
||||
import {
|
||||
FetchDataParams,
|
||||
|
@ -34,10 +32,10 @@ import {
|
|||
TriggersAndActionsUIPublicPluginSetup,
|
||||
TriggersAndActionsUIPublicPluginStart,
|
||||
} from '../../triggers_actions_ui/public';
|
||||
import { AlertType } from '../common/alert_types';
|
||||
import { featureCatalogueEntry } from './featureCatalogueEntry';
|
||||
import { toggleAppLinkInNav } from './toggleAppLinkInNav';
|
||||
import { EmbeddableStart } from '../../../../src/plugins/embeddable/public';
|
||||
import { registerApmAlerts } from './components/alerting/register_apm_alerts';
|
||||
|
||||
export type ApmPluginSetup = void;
|
||||
export type ApmPluginStart = void;
|
||||
|
@ -147,51 +145,6 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
|
|||
}
|
||||
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
|
||||
toggleAppLinkInNav(core, this.initializerContext.config.get());
|
||||
|
||||
plugins.triggers_actions_ui.alertTypeRegistry.register({
|
||||
id: AlertType.ErrorRate,
|
||||
name: i18n.translate('xpack.apm.alertTypes.errorRate', {
|
||||
defaultMessage: 'Error rate',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() => import('./components/shared/ErrorRateAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
|
||||
plugins.triggers_actions_ui.alertTypeRegistry.register({
|
||||
id: AlertType.TransactionDuration,
|
||||
name: i18n.translate('xpack.apm.alertTypes.transactionDuration', {
|
||||
defaultMessage: 'Transaction duration',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() => import('./components/shared/TransactionDurationAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
|
||||
plugins.triggers_actions_ui.alertTypeRegistry.register({
|
||||
id: AlertType.TransactionDurationAnomaly,
|
||||
name: i18n.translate('xpack.apm.alertTypes.transactionDurationAnomaly', {
|
||||
defaultMessage: 'Transaction duration anomaly',
|
||||
}),
|
||||
iconClass: 'bell',
|
||||
alertParamsExpression: lazy(
|
||||
() =>
|
||||
import('./components/shared/TransactionDurationAnomalyAlertTrigger')
|
||||
),
|
||||
validate: () => ({
|
||||
errors: [],
|
||||
}),
|
||||
requiresAppContext: true,
|
||||
});
|
||||
registerApmAlerts(plugins.triggers_actions_ui.alertTypeRegistry);
|
||||
}
|
||||
}
|
||||
|
|
48
x-pack/plugins/apm/server/lib/alerts/action_variables.ts
Normal file
48
x-pack/plugins/apm/server/lib/alerts/action_variables.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
|
||||
export const apmActionVariables = {
|
||||
serviceName: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.serviceName',
|
||||
{ defaultMessage: 'The service the alert is created for' }
|
||||
),
|
||||
name: 'serviceName',
|
||||
},
|
||||
transactionType: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.transactionType',
|
||||
{ defaultMessage: 'The transaction type the alert is created for' }
|
||||
),
|
||||
name: 'transactionType',
|
||||
},
|
||||
environment: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.environment',
|
||||
{ defaultMessage: 'The transaction type the alert is created for' }
|
||||
),
|
||||
name: 'environment',
|
||||
},
|
||||
threshold: {
|
||||
description: i18n.translate('xpack.apm.alerts.action_variables.threshold', {
|
||||
defaultMessage:
|
||||
'Any trigger value above this value will cause the alert to fire',
|
||||
}),
|
||||
name: 'threshold',
|
||||
},
|
||||
triggerValue: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.triggerValue',
|
||||
{
|
||||
defaultMessage:
|
||||
'The value that breached the threshold and triggered the alert',
|
||||
}
|
||||
),
|
||||
name: 'triggerValue',
|
||||
},
|
||||
};
|
|
@ -9,9 +9,10 @@ import { AlertingPlugin } from '../../../../alerts/server';
|
|||
import { ActionsPlugin } from '../../../../actions/server';
|
||||
import { registerTransactionDurationAlertType } from './register_transaction_duration_alert_type';
|
||||
import { registerTransactionDurationAnomalyAlertType } from './register_transaction_duration_anomaly_alert_type';
|
||||
import { registerErrorRateAlertType } from './register_error_rate_alert_type';
|
||||
import { registerErrorCountAlertType } from './register_error_count_alert_type';
|
||||
import { APMConfig } from '../..';
|
||||
import { MlPluginSetup } from '../../../../ml/server';
|
||||
import { registerTransactionErrorRateAlertType } from './register_transaction_error_rate_alert_type';
|
||||
|
||||
interface Params {
|
||||
alerts: AlertingPlugin['setup'];
|
||||
|
@ -30,7 +31,11 @@ export function registerApmAlerts(params: Params) {
|
|||
ml: params.ml,
|
||||
config$: params.config$,
|
||||
});
|
||||
registerErrorRateAlertType({
|
||||
registerErrorCountAlertType({
|
||||
alerts: params.alerts,
|
||||
config$: params.config$,
|
||||
});
|
||||
registerTransactionErrorRateAlertType({
|
||||
alerts: params.alerts,
|
||||
config$: params.config$,
|
||||
});
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { schema } 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 { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { getEnvironmentUiFilterES } from '../helpers/convert_ui_filters/get_environment_ui_filter_es';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import {
|
||||
ESSearchResponse,
|
||||
|
@ -17,11 +17,11 @@ import {
|
|||
import {
|
||||
PROCESSOR_EVENT,
|
||||
SERVICE_NAME,
|
||||
SERVICE_ENVIRONMENT,
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { AlertingPlugin } from '../../../../alerts/server';
|
||||
import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
|
||||
import { APMConfig } from '../..';
|
||||
import { apmActionVariables } from './action_variables';
|
||||
|
||||
interface RegisterAlertParams {
|
||||
alerts: AlertingPlugin['setup'];
|
||||
|
@ -29,21 +29,21 @@ interface RegisterAlertParams {
|
|||
}
|
||||
|
||||
const paramsSchema = schema.object({
|
||||
serviceName: schema.string(),
|
||||
windowSize: schema.number(),
|
||||
windowUnit: schema.string(),
|
||||
threshold: schema.number(),
|
||||
serviceName: schema.string(),
|
||||
environment: schema.string(),
|
||||
});
|
||||
|
||||
const alertTypeConfig = ALERT_TYPES_CONFIG[AlertType.ErrorRate];
|
||||
const alertTypeConfig = ALERT_TYPES_CONFIG[AlertType.ErrorCount];
|
||||
|
||||
export function registerErrorRateAlertType({
|
||||
export function registerErrorCountAlertType({
|
||||
alerts,
|
||||
config$,
|
||||
}: RegisterAlertParams) {
|
||||
alerts.registerType({
|
||||
id: AlertType.ErrorRate,
|
||||
id: AlertType.ErrorCount,
|
||||
name: alertTypeConfig.name,
|
||||
actionGroups: alertTypeConfig.actionGroups,
|
||||
defaultActionGroupId: alertTypeConfig.defaultActionGroupId,
|
||||
|
@ -52,37 +52,26 @@ export function registerErrorRateAlertType({
|
|||
},
|
||||
actionVariables: {
|
||||
context: [
|
||||
{
|
||||
description: i18n.translate(
|
||||
'xpack.apm.registerErrorRateAlertType.variables.serviceName',
|
||||
{
|
||||
defaultMessage: 'Service name',
|
||||
}
|
||||
),
|
||||
name: 'serviceName',
|
||||
},
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.environment,
|
||||
apmActionVariables.threshold,
|
||||
apmActionVariables.triggerValue,
|
||||
],
|
||||
},
|
||||
producer: 'apm',
|
||||
executor: async ({ services, params }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
|
||||
const alertParams = params as TypeOf<typeof paramsSchema>;
|
||||
|
||||
const alertParams = params;
|
||||
const indices = await getApmIndices({
|
||||
config,
|
||||
savedObjectsClient: services.savedObjectsClient,
|
||||
});
|
||||
|
||||
const environmentTerm =
|
||||
alertParams.environment === ENVIRONMENT_ALL.value
|
||||
? []
|
||||
: [{ term: { [SERVICE_ENVIRONMENT]: alertParams.environment } }];
|
||||
|
||||
const searchParams = {
|
||||
index: indices['apm_oss.errorIndices'],
|
||||
size: 0,
|
||||
body: {
|
||||
track_total_hits: true,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
|
@ -93,21 +82,12 @@ export function registerErrorRateAlertType({
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
[PROCESSOR_EVENT]: 'error',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
[SERVICE_NAME]: alertParams.serviceName,
|
||||
},
|
||||
},
|
||||
...environmentTerm,
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.error } },
|
||||
{ term: { [SERVICE_NAME]: alertParams.serviceName } },
|
||||
...getEnvironmentUiFilterES(alertParams.environment),
|
||||
],
|
||||
},
|
||||
},
|
||||
track_total_hits: true,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -116,18 +96,19 @@ export function registerErrorRateAlertType({
|
|||
ESSearchRequest
|
||||
> = await services.callCluster('search', searchParams);
|
||||
|
||||
const value = response.hits.total.value;
|
||||
const errorCount = response.hits.total.value;
|
||||
|
||||
if (value && value > alertParams.threshold) {
|
||||
if (errorCount > alertParams.threshold) {
|
||||
const alertInstance = services.alertInstanceFactory(
|
||||
AlertType.ErrorRate
|
||||
AlertType.ErrorCount
|
||||
);
|
||||
alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, {
|
||||
serviceName: alertParams.serviceName,
|
||||
environment: alertParams.environment,
|
||||
threshold: alertParams.threshold,
|
||||
triggerValue: errorCount,
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
});
|
||||
}
|
|
@ -4,11 +4,10 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { schema } 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 { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import { ESSearchResponse } from '../../../typings/elasticsearch';
|
||||
import {
|
||||
|
@ -16,11 +15,12 @@ import {
|
|||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
TRANSACTION_DURATION,
|
||||
SERVICE_ENVIRONMENT,
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { AlertingPlugin } from '../../../../alerts/server';
|
||||
import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
|
||||
import { APMConfig } from '../..';
|
||||
import { getEnvironmentUiFilterES } from '../helpers/convert_ui_filters/get_environment_ui_filter_es';
|
||||
import { apmActionVariables } from './action_variables';
|
||||
|
||||
interface RegisterAlertParams {
|
||||
alerts: AlertingPlugin['setup'];
|
||||
|
@ -57,42 +57,22 @@ export function registerTransactionDurationAlertType({
|
|||
},
|
||||
actionVariables: {
|
||||
context: [
|
||||
{
|
||||
description: i18n.translate(
|
||||
'xpack.apm.registerTransactionDurationAlertType.variables.serviceName',
|
||||
{
|
||||
defaultMessage: 'Service name',
|
||||
}
|
||||
),
|
||||
name: 'serviceName',
|
||||
},
|
||||
{
|
||||
description: i18n.translate(
|
||||
'xpack.apm.registerTransactionDurationAlertType.variables.transactionType',
|
||||
{
|
||||
defaultMessage: 'Transaction type',
|
||||
}
|
||||
),
|
||||
name: 'transactionType',
|
||||
},
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.transactionType,
|
||||
apmActionVariables.environment,
|
||||
apmActionVariables.threshold,
|
||||
apmActionVariables.triggerValue,
|
||||
],
|
||||
},
|
||||
producer: 'apm',
|
||||
executor: async ({ services, params }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
|
||||
const alertParams = params as TypeOf<typeof paramsSchema>;
|
||||
|
||||
const alertParams = params;
|
||||
const indices = await getApmIndices({
|
||||
config,
|
||||
savedObjectsClient: services.savedObjectsClient,
|
||||
});
|
||||
|
||||
const environmentTerm =
|
||||
alertParams.environment === ENVIRONMENT_ALL.value
|
||||
? []
|
||||
: [{ term: { [SERVICE_ENVIRONMENT]: alertParams.environment } }];
|
||||
|
||||
const searchParams = {
|
||||
index: indices['apm_oss.transactionIndices'],
|
||||
size: 0,
|
||||
|
@ -107,33 +87,17 @@ export function registerTransactionDurationAlertType({
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
[PROCESSOR_EVENT]: 'transaction',
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
[SERVICE_NAME]: alertParams.serviceName,
|
||||
},
|
||||
},
|
||||
{
|
||||
term: {
|
||||
[TRANSACTION_TYPE]: alertParams.transactionType,
|
||||
},
|
||||
},
|
||||
...environmentTerm,
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
{ term: { [SERVICE_NAME]: alertParams.serviceName } },
|
||||
{ term: { [TRANSACTION_TYPE]: alertParams.transactionType } },
|
||||
...getEnvironmentUiFilterES(alertParams.environment),
|
||||
],
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
agg:
|
||||
alertParams.aggregationType === 'avg'
|
||||
? {
|
||||
avg: {
|
||||
field: TRANSACTION_DURATION,
|
||||
},
|
||||
}
|
||||
? { avg: { field: TRANSACTION_DURATION } }
|
||||
: {
|
||||
percentiles: {
|
||||
field: TRANSACTION_DURATION,
|
||||
|
@ -157,19 +121,23 @@ export function registerTransactionDurationAlertType({
|
|||
|
||||
const { agg } = response.aggregations;
|
||||
|
||||
const value = 'values' in agg ? Object.values(agg.values)[0] : agg?.value;
|
||||
const transactionDuration =
|
||||
'values' in agg ? Object.values(agg.values)[0] : agg?.value;
|
||||
|
||||
if (value && value > alertParams.threshold * 1000) {
|
||||
const threshold = alertParams.threshold * 1000;
|
||||
|
||||
if (transactionDuration && transactionDuration > threshold) {
|
||||
const alertInstance = services.alertInstanceFactory(
|
||||
AlertType.TransactionDuration
|
||||
);
|
||||
alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, {
|
||||
transactionType: alertParams.transactionType,
|
||||
serviceName: alertParams.serviceName,
|
||||
environment: alertParams.environment,
|
||||
threshold,
|
||||
triggerValue: transactionDuration,
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { schema, TypeOf } from '@kbn/config-schema';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { Observable } from 'rxjs';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KibanaRequest } from '../../../../../../src/core/server';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import { AlertingPlugin } from '../../../../alerts/server';
|
||||
import { APMConfig } from '../..';
|
||||
import { MlPluginSetup } from '../../../../ml/server';
|
||||
import { getMLJobIds } from '../service_map/get_service_anomalies';
|
||||
import { apmActionVariables } from './action_variables';
|
||||
|
||||
interface RegisterAlertParams {
|
||||
alerts: AlertingPlugin['setup'];
|
||||
|
@ -47,24 +47,9 @@ export function registerTransactionDurationAnomalyAlertType({
|
|||
},
|
||||
actionVariables: {
|
||||
context: [
|
||||
{
|
||||
description: i18n.translate(
|
||||
'xpack.apm.registerTransactionDurationAnomalyAlertType.variables.serviceName',
|
||||
{
|
||||
defaultMessage: 'Service name',
|
||||
}
|
||||
),
|
||||
name: 'serviceName',
|
||||
},
|
||||
{
|
||||
description: i18n.translate(
|
||||
'xpack.apm.registerTransactionDurationAnomalyAlertType.variables.transactionType',
|
||||
{
|
||||
defaultMessage: 'Transaction type',
|
||||
}
|
||||
),
|
||||
name: 'transactionType',
|
||||
},
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.transactionType,
|
||||
apmActionVariables.environment,
|
||||
],
|
||||
},
|
||||
producer: 'apm',
|
||||
|
@ -72,7 +57,7 @@ export function registerTransactionDurationAnomalyAlertType({
|
|||
if (!ml) {
|
||||
return;
|
||||
}
|
||||
const alertParams = params as TypeOf<typeof paramsSchema>;
|
||||
const alertParams = params;
|
||||
const request = {} as KibanaRequest;
|
||||
const { mlAnomalySearch } = ml.mlSystemProvider(request);
|
||||
const anomalyDetectors = ml.anomalyDetectorsProvider(request);
|
||||
|
@ -88,6 +73,7 @@ export function registerTransactionDurationAnomalyAlertType({
|
|||
|
||||
const anomalySearchParams = {
|
||||
body: {
|
||||
terminateAfter: 1,
|
||||
size: 0,
|
||||
query: {
|
||||
bool: {
|
||||
|
@ -131,10 +117,10 @@ export function registerTransactionDurationAnomalyAlertType({
|
|||
);
|
||||
alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, {
|
||||
serviceName: alertParams.serviceName,
|
||||
transactionType: alertParams.transactionType,
|
||||
environment: alertParams.environment,
|
||||
});
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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 { schema } from '@kbn/config-schema';
|
||||
import { Observable } from 'rxjs';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { EventOutcome } from '../../../common/event_outcome';
|
||||
import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types';
|
||||
import { ESSearchResponse } from '../../../typings/elasticsearch';
|
||||
import {
|
||||
PROCESSOR_EVENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
EVENT_OUTCOME,
|
||||
} from '../../../common/elasticsearch_fieldnames';
|
||||
import { AlertingPlugin } from '../../../../alerts/server';
|
||||
import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
|
||||
import { APMConfig } from '../..';
|
||||
import { getEnvironmentUiFilterES } from '../helpers/convert_ui_filters/get_environment_ui_filter_es';
|
||||
import { apmActionVariables } from './action_variables';
|
||||
|
||||
interface RegisterAlertParams {
|
||||
alerts: AlertingPlugin['setup'];
|
||||
config$: Observable<APMConfig>;
|
||||
}
|
||||
|
||||
const paramsSchema = schema.object({
|
||||
windowSize: schema.number(),
|
||||
windowUnit: schema.string(),
|
||||
threshold: schema.number(),
|
||||
transactionType: schema.string(),
|
||||
serviceName: schema.string(),
|
||||
environment: schema.string(),
|
||||
});
|
||||
|
||||
const alertTypeConfig = ALERT_TYPES_CONFIG[AlertType.TransactionErrorRate];
|
||||
|
||||
export function registerTransactionErrorRateAlertType({
|
||||
alerts,
|
||||
config$,
|
||||
}: RegisterAlertParams) {
|
||||
alerts.registerType({
|
||||
id: AlertType.TransactionErrorRate,
|
||||
name: alertTypeConfig.name,
|
||||
actionGroups: alertTypeConfig.actionGroups,
|
||||
defaultActionGroupId: alertTypeConfig.defaultActionGroupId,
|
||||
validate: {
|
||||
params: paramsSchema,
|
||||
},
|
||||
actionVariables: {
|
||||
context: [
|
||||
apmActionVariables.transactionType,
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.environment,
|
||||
apmActionVariables.threshold,
|
||||
apmActionVariables.triggerValue,
|
||||
],
|
||||
},
|
||||
producer: 'apm',
|
||||
executor: async ({ services, params: alertParams }) => {
|
||||
const config = await config$.pipe(take(1)).toPromise();
|
||||
const indices = await getApmIndices({
|
||||
config,
|
||||
savedObjectsClient: services.savedObjectsClient,
|
||||
});
|
||||
|
||||
const searchParams = {
|
||||
index: indices['apm_oss.transactionIndices'],
|
||||
size: 0,
|
||||
body: {
|
||||
track_total_hits: true,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{
|
||||
range: {
|
||||
'@timestamp': {
|
||||
gte: `now-${alertParams.windowSize}${alertParams.windowUnit}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
{ term: { [SERVICE_NAME]: alertParams.serviceName } },
|
||||
{ term: { [TRANSACTION_TYPE]: alertParams.transactionType } },
|
||||
...getEnvironmentUiFilterES(alertParams.environment),
|
||||
],
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
erroneous_transactions: {
|
||||
filter: { term: { [EVENT_OUTCOME]: EventOutcome.failure } },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const response: ESSearchResponse<
|
||||
unknown,
|
||||
typeof searchParams
|
||||
> = await services.callCluster('search', searchParams);
|
||||
|
||||
if (!response.aggregations) {
|
||||
return;
|
||||
}
|
||||
|
||||
const errornousTransactionsCount =
|
||||
response.aggregations.erroneous_transactions.doc_count;
|
||||
const totalTransactionCount = response.hits.total.value;
|
||||
const transactionErrorRate =
|
||||
(errornousTransactionsCount / totalTransactionCount) * 100;
|
||||
|
||||
if (transactionErrorRate > alertParams.threshold) {
|
||||
const alertInstance = services.alertInstanceFactory(
|
||||
AlertType.TransactionErrorRate
|
||||
);
|
||||
|
||||
alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, {
|
||||
serviceName: alertParams.serviceName,
|
||||
transactionType: alertParams.transactionType,
|
||||
environment: alertParams.environment,
|
||||
threshold: alertParams.threshold,
|
||||
triggerValue: transactionErrorRate,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
|
@ -8,6 +8,7 @@ import { Logger } from 'kibana/server';
|
|||
import uuid from 'uuid/v4';
|
||||
import { snakeCase } from 'lodash';
|
||||
import Boom from 'boom';
|
||||
import { ProcessorEvent } from '../../../common/processor_event';
|
||||
import { ML_ERRORS } from '../../../common/anomaly_detection';
|
||||
import { PromiseReturnType } from '../../../../observability/typings/common';
|
||||
import { Setup } from '../helpers/setup_request';
|
||||
|
@ -79,7 +80,7 @@ async function createAnomalyDetectionJob({
|
|||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
{ exists: { field: TRANSACTION_DURATION } },
|
||||
...getEnvironmentUiFilterES(environment),
|
||||
],
|
||||
|
|
|
@ -85,7 +85,7 @@ export const tasks: TelemetryTask[] = [
|
|||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
{ range: { '@timestamp': { gte: start, lt: end } } },
|
||||
],
|
||||
},
|
||||
|
@ -606,7 +606,10 @@ export const tasks: TelemetryTask[] = [
|
|||
timeout,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [{ term: { [PROCESSOR_EVENT]: 'error' } }, range1d],
|
||||
filter: [
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.error } },
|
||||
range1d,
|
||||
],
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
|
@ -640,7 +643,7 @@ export const tasks: TelemetryTask[] = [
|
|||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
range1d,
|
||||
],
|
||||
},
|
||||
|
@ -674,7 +677,7 @@ export const tasks: TelemetryTask[] = [
|
|||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.transaction } },
|
||||
range1d,
|
||||
],
|
||||
must_not: {
|
||||
|
|
|
@ -5,11 +5,14 @@
|
|||
*/
|
||||
|
||||
import { ESFilter } from '../../../../typings/elasticsearch';
|
||||
import { ENVIRONMENT_NOT_DEFINED } from '../../../../common/environment_filter_values';
|
||||
import {
|
||||
ENVIRONMENT_NOT_DEFINED,
|
||||
ENVIRONMENT_ALL,
|
||||
} from '../../../../common/environment_filter_values';
|
||||
import { SERVICE_ENVIRONMENT } from '../../../../common/elasticsearch_fieldnames';
|
||||
|
||||
export function getEnvironmentUiFilterES(environment?: string): ESFilter[] {
|
||||
if (!environment) {
|
||||
if (!environment || environment === ENVIRONMENT_ALL.value) {
|
||||
return [];
|
||||
}
|
||||
if (environment === ENVIRONMENT_NOT_DEFINED.value) {
|
||||
|
|
|
@ -67,7 +67,7 @@ export async function getPageViewTrends({
|
|||
x: xVal,
|
||||
y: bCount,
|
||||
};
|
||||
if (breakdownItem) {
|
||||
if ('breakdown' in bucket) {
|
||||
const categoryBuckets = bucket.breakdown.buckets;
|
||||
categoryBuckets.forEach(({ key, doc_count: docCount }) => {
|
||||
if (key === 'Other') {
|
||||
|
|
|
@ -4616,7 +4616,6 @@
|
|||
"xpack.apm.agentMetrics.java.threadCount": "平均カウント",
|
||||
"xpack.apm.agentMetrics.java.threadCountChartTitle": "スレッド数",
|
||||
"xpack.apm.agentMetrics.java.threadCountMax": "最高カウント",
|
||||
"xpack.apm.alertTypes.errorRate": "エラー率",
|
||||
"xpack.apm.alertTypes.transactionDuration": "トランザクション期間",
|
||||
"xpack.apm.anomaly_detection.error.invalid_license": "異常検知を使用するには、Elastic Platinumライセンスのサブスクリプションが必要です。このライセンスがあれば、機械学習を活用して、サービスを監視できます。",
|
||||
"xpack.apm.anomaly_detection.error.missing_read_privileges": "異常検知ジョブを表示するには、機械学習およびAPMの「読み取り」権限が必要です",
|
||||
|
@ -4675,11 +4674,6 @@
|
|||
"xpack.apm.errorGroupDetails.relatedTransactionSample": "関連トランザクションサンプル",
|
||||
"xpack.apm.errorGroupDetails.unhandledLabel": "未対応",
|
||||
"xpack.apm.errorGroupDetails.viewOccurrencesInDiscoverButtonLabel": "ディスカバリで {occurrencesCount} 件の{occurrencesCount, plural, one {ドキュメント} other {ドキュメント}}を表示。",
|
||||
"xpack.apm.errorRateAlert.name": "エラー率",
|
||||
"xpack.apm.errorRateAlert.thresholdMet": "しきい値一致",
|
||||
"xpack.apm.errorRateAlertTrigger.environment": "環境",
|
||||
"xpack.apm.errorRateAlertTrigger.errors": "エラー",
|
||||
"xpack.apm.errorRateAlertTrigger.isAbove": "の下限は",
|
||||
"xpack.apm.errorRateChart.avgLabel": "平均",
|
||||
"xpack.apm.errorRateChart.rateLabel": "レート",
|
||||
"xpack.apm.errorRateChart.title": "トランザクションエラー率",
|
||||
|
@ -4781,9 +4775,6 @@
|
|||
"xpack.apm.propertiesTable.tabs.logStacktraceLabel": "スタックトレース",
|
||||
"xpack.apm.propertiesTable.tabs.metadataLabel": "メタデータ",
|
||||
"xpack.apm.propertiesTable.tabs.timelineLabel": "タイムライン",
|
||||
"xpack.apm.registerErrorRateAlertType.variables.serviceName": "サービス名",
|
||||
"xpack.apm.registerTransactionDurationAlertType.variables.serviceName": "サービス名",
|
||||
"xpack.apm.registerTransactionDurationAlertType.variables.transactionType": "トランザクションタイプ",
|
||||
"xpack.apm.rum.dashboard.backend": "バックエンド",
|
||||
"xpack.apm.rum.dashboard.frontend": "フロントエンド",
|
||||
"xpack.apm.rum.dashboard.overall.label": "全体",
|
||||
|
@ -4801,7 +4792,6 @@
|
|||
"xpack.apm.selectPlaceholder": "オプションを選択:",
|
||||
"xpack.apm.serviceDetails.alertsMenu.alerts": "アラート",
|
||||
"xpack.apm.serviceDetails.alertsMenu.createThresholdAlert": "しきい値アラートを作成",
|
||||
"xpack.apm.serviceDetails.alertsMenu.errorRate": "エラー率",
|
||||
"xpack.apm.serviceDetails.alertsMenu.transactionDuration": "トランザクション期間",
|
||||
"xpack.apm.serviceDetails.alertsMenu.viewActiveAlerts": "アクティブアラートを表示",
|
||||
"xpack.apm.serviceDetails.errorsTabLabel": "エラー",
|
||||
|
@ -5031,11 +5021,7 @@
|
|||
"xpack.apm.transactionDurationAlert.aggregationType.99th": "99 パーセンタイル",
|
||||
"xpack.apm.transactionDurationAlert.aggregationType.avg": "平均",
|
||||
"xpack.apm.transactionDurationAlert.name": "トランザクション期間",
|
||||
"xpack.apm.transactionDurationAlert.thresholdMet": "しきい値一致",
|
||||
"xpack.apm.transactionDurationAlertTrigger.environment": "環境",
|
||||
"xpack.apm.transactionDurationAlertTrigger.isAbove": "の下限は",
|
||||
"xpack.apm.transactionDurationAlertTrigger.ms": "ms",
|
||||
"xpack.apm.transactionDurationAlertTrigger.type": "タイプ",
|
||||
"xpack.apm.transactionDurationAlertTrigger.when": "タイミング",
|
||||
"xpack.apm.transactionDurationLabel": "期間",
|
||||
"xpack.apm.transactions.chart.95thPercentileLabel": "95 パーセンタイル",
|
||||
|
|
|
@ -4617,7 +4617,6 @@
|
|||
"xpack.apm.agentMetrics.java.threadCount": "平均计数",
|
||||
"xpack.apm.agentMetrics.java.threadCountChartTitle": "线程计数",
|
||||
"xpack.apm.agentMetrics.java.threadCountMax": "最大计数",
|
||||
"xpack.apm.alertTypes.errorRate": "错误率",
|
||||
"xpack.apm.alertTypes.transactionDuration": "事务持续时间",
|
||||
"xpack.apm.anomaly_detection.error.invalid_license": "要使用异常检测,必须订阅 Elastic 白金级许可证。有了该许可证,您便可借助 Machine Learning 监测服务。",
|
||||
"xpack.apm.anomaly_detection.error.missing_read_privileges": "必须对 Machine Learning 和 APM 具有“读”权限,才能查看“异常检测”作业",
|
||||
|
@ -4676,11 +4675,6 @@
|
|||
"xpack.apm.errorGroupDetails.relatedTransactionSample": "相关的事务样本",
|
||||
"xpack.apm.errorGroupDetails.unhandledLabel": "未处理",
|
||||
"xpack.apm.errorGroupDetails.viewOccurrencesInDiscoverButtonLabel": "在 Discover 查看 {occurrencesCount} 个 {occurrencesCount, plural, one {匹配项} other {匹配项}}。",
|
||||
"xpack.apm.errorRateAlert.name": "错误率",
|
||||
"xpack.apm.errorRateAlert.thresholdMet": "阈值已达到",
|
||||
"xpack.apm.errorRateAlertTrigger.environment": "环境",
|
||||
"xpack.apm.errorRateAlertTrigger.errors": "错误",
|
||||
"xpack.apm.errorRateAlertTrigger.isAbove": "高于",
|
||||
"xpack.apm.errorRateChart.avgLabel": "平均",
|
||||
"xpack.apm.errorRateChart.rateLabel": "比率",
|
||||
"xpack.apm.errorRateChart.title": "事务错误率",
|
||||
|
@ -4784,9 +4778,6 @@
|
|||
"xpack.apm.propertiesTable.tabs.logStacktraceLabel": "日志堆栈跟踪",
|
||||
"xpack.apm.propertiesTable.tabs.metadataLabel": "元数据",
|
||||
"xpack.apm.propertiesTable.tabs.timelineLabel": "时间线",
|
||||
"xpack.apm.registerErrorRateAlertType.variables.serviceName": "服务名称",
|
||||
"xpack.apm.registerTransactionDurationAlertType.variables.serviceName": "服务名称",
|
||||
"xpack.apm.registerTransactionDurationAlertType.variables.transactionType": "事务类型",
|
||||
"xpack.apm.rum.dashboard.backend": "后端",
|
||||
"xpack.apm.rum.dashboard.frontend": "前端",
|
||||
"xpack.apm.rum.dashboard.overall.label": "总体",
|
||||
|
@ -4804,7 +4795,6 @@
|
|||
"xpack.apm.selectPlaceholder": "选择选项:",
|
||||
"xpack.apm.serviceDetails.alertsMenu.alerts": "告警",
|
||||
"xpack.apm.serviceDetails.alertsMenu.createThresholdAlert": "创建阈值告警",
|
||||
"xpack.apm.serviceDetails.alertsMenu.errorRate": "错误率",
|
||||
"xpack.apm.serviceDetails.alertsMenu.transactionDuration": "事务持续时间",
|
||||
"xpack.apm.serviceDetails.alertsMenu.viewActiveAlerts": "查看活动的告警",
|
||||
"xpack.apm.serviceDetails.errorsTabLabel": "错误",
|
||||
|
@ -5034,11 +5024,7 @@
|
|||
"xpack.apm.transactionDurationAlert.aggregationType.99th": "第 99 个百分位",
|
||||
"xpack.apm.transactionDurationAlert.aggregationType.avg": "平均值",
|
||||
"xpack.apm.transactionDurationAlert.name": "事务持续时间",
|
||||
"xpack.apm.transactionDurationAlert.thresholdMet": "阈值已达到",
|
||||
"xpack.apm.transactionDurationAlertTrigger.environment": "环境",
|
||||
"xpack.apm.transactionDurationAlertTrigger.isAbove": "高于",
|
||||
"xpack.apm.transactionDurationAlertTrigger.ms": "ms",
|
||||
"xpack.apm.transactionDurationAlertTrigger.type": "类型",
|
||||
"xpack.apm.transactionDurationAlertTrigger.when": "当",
|
||||
"xpack.apm.transactionDurationLabel": "持续时间",
|
||||
"xpack.apm.transactions.chart.95thPercentileLabel": "第 95 个百分位",
|
||||
|
|
Loading…
Reference in a new issue