From 33cfd9eea5637bf9aa5f4f2f2c4fe3c0ee8f2864 Mon Sep 17 00:00:00 2001 From: cauemarcondes Date: Fri, 2 Oct 2020 16:39:29 +0200 Subject: [PATCH] addressing pr comments --- x-pack/plugins/apm/common/utils/formatters.ts | 28 ------------- .../utils/formatters}/datetime.test.ts | 2 +- .../utils/formatters/datetime.ts | 0 .../utils/formatters}/duration.test.ts | 2 +- .../utils/formatters/duration.ts | 0 .../utils/{ => formatters}/formatters.test.ts | 0 .../utils/formatters/formatters.ts | 21 ++++++++++ .../utils/formatters/index.ts | 0 .../utils/formatters}/size.test.ts | 2 +- .../utils/formatters/size.ts | 0 .../alerting/register_apm_alerts.ts | 24 ++++++----- .../ErrorGroupDetails/Distribution/index.tsx | 2 +- .../ServiceMap/Popover/AnomalyDetection.tsx | 2 +- .../ServiceMap/Popover/ServiceStatsList.tsx | 7 +++- .../app/ServiceNodeOverview/index.tsx | 7 +++- .../app/ServiceOverview/ServiceList/index.tsx | 7 +++- .../app/TraceOverview/TraceList.tsx | 2 +- .../TransactionDetails/Distribution/index.tsx | 2 +- .../Waterfall/WaterfallItem.tsx | 2 +- .../TransactionList/index.tsx | 5 ++- .../shared/Summary/DurationSummaryItem.tsx | 2 +- .../shared/TimestampTooltip/index.tsx | 5 ++- .../charts/CustomPlot/AnnotationsPlot.tsx | 2 +- .../Histogram/__test__/Histogram.test.js | 8 ++-- .../shared/charts/MetricsChart/index.tsx | 12 +++--- .../charts/Timeline/Marker/AgentMarker.tsx | 2 +- .../charts/Timeline/Marker/ErrorMarker.tsx | 2 +- .../shared/charts/Timeline/TimelineAxis.tsx | 2 +- .../components/shared/charts/Tooltip/index.js | 2 +- .../charts/TransactionCharts/helper.test.ts | 5 ++- .../charts/TransactionCharts/helper.tsx | 2 +- .../shared/charts/TransactionCharts/index.tsx | 2 +- .../TransactionCharts/use_formatter.test.tsx | 2 +- .../charts/TransactionCharts/use_formatter.ts | 2 +- .../apm/public/selectors/chartSelectors.ts | 2 +- .../apm/server/lib/alerts/action_variables.ts | 20 ++++++++++ .../register_error_count_alert_type.test.ts | 16 +++++++- .../alerts/register_error_count_alert_type.ts | 4 ++ ...egister_transaction_duration_alert_type.ts | 40 ++++++++++++++----- ...action_duration_anomaly_alert_type.test.ts | 13 +++++- ...transaction_duration_anomaly_alert_type.ts | 23 +++++++++-- ..._transaction_error_rate_alert_type.test.ts | 38 +++++++++++++----- ...ister_transaction_error_rate_alert_type.ts | 8 +++- 43 files changed, 223 insertions(+), 106 deletions(-) delete mode 100644 x-pack/plugins/apm/common/utils/formatters.ts rename x-pack/plugins/apm/{public/utils/formatters/__test__ => common/utils/formatters}/datetime.test.ts (99%) rename x-pack/plugins/apm/{public => common}/utils/formatters/datetime.ts (100%) rename x-pack/plugins/apm/{public/utils/formatters/__test__ => common/utils/formatters}/duration.test.ts (99%) rename x-pack/plugins/apm/{public => common}/utils/formatters/duration.ts (100%) rename x-pack/plugins/apm/common/utils/{ => formatters}/formatters.test.ts (100%) rename x-pack/plugins/apm/{public => common}/utils/formatters/formatters.ts (65%) rename x-pack/plugins/apm/{public => common}/utils/formatters/index.ts (100%) rename x-pack/plugins/apm/{public/utils/formatters/__test__ => common/utils/formatters}/size.test.ts (97%) rename x-pack/plugins/apm/{public => common}/utils/formatters/size.ts (100%) diff --git a/x-pack/plugins/apm/common/utils/formatters.ts b/x-pack/plugins/apm/common/utils/formatters.ts deleted file mode 100644 index f7c609d949adf..0000000000000 --- a/x-pack/plugins/apm/common/utils/formatters.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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 numeral from '@elastic/numeral'; - -export function asPercent( - numerator: number, - denominator: number | undefined, - fallbackResult = '' -) { - if (!denominator || isNaN(numerator)) { - return fallbackResult; - } - - const decimal = numerator / denominator; - - // 33.2 => 33% - // 3.32 => 3.3% - // 0 => 0% - if (Math.abs(decimal) >= 0.1 || decimal === 0) { - return numeral(decimal).format('0%'); - } - - return numeral(decimal).format('0.0%'); -} diff --git a/x-pack/plugins/apm/public/utils/formatters/__test__/datetime.test.ts b/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts similarity index 99% rename from x-pack/plugins/apm/public/utils/formatters/__test__/datetime.test.ts rename to x-pack/plugins/apm/common/utils/formatters/datetime.test.ts index 647a27c59aa4c..733fb7bb5eea1 100644 --- a/x-pack/plugins/apm/public/utils/formatters/__test__/datetime.test.ts +++ b/x-pack/plugins/apm/common/utils/formatters/datetime.test.ts @@ -8,7 +8,7 @@ import { asRelativeDateTimeRange, asAbsoluteDateTime, getDateDifference, -} from '../datetime'; +} from './datetime'; describe('date time formatters', () => { beforeAll(() => { diff --git a/x-pack/plugins/apm/public/utils/formatters/datetime.ts b/x-pack/plugins/apm/common/utils/formatters/datetime.ts similarity index 100% rename from x-pack/plugins/apm/public/utils/formatters/datetime.ts rename to x-pack/plugins/apm/common/utils/formatters/datetime.ts diff --git a/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts b/x-pack/plugins/apm/common/utils/formatters/duration.test.ts similarity index 99% rename from x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts rename to x-pack/plugins/apm/common/utils/formatters/duration.test.ts index ca8a4919dd216..a39d9b47f41c2 100644 --- a/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts +++ b/x-pack/plugins/apm/common/utils/formatters/duration.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { asDuration, toMicroseconds, asMillisecondDuration } from '../duration'; +import { asDuration, toMicroseconds, asMillisecondDuration } from './duration'; describe('duration formatters', () => { describe('asDuration', () => { diff --git a/x-pack/plugins/apm/public/utils/formatters/duration.ts b/x-pack/plugins/apm/common/utils/formatters/duration.ts similarity index 100% rename from x-pack/plugins/apm/public/utils/formatters/duration.ts rename to x-pack/plugins/apm/common/utils/formatters/duration.ts diff --git a/x-pack/plugins/apm/common/utils/formatters.test.ts b/x-pack/plugins/apm/common/utils/formatters/formatters.test.ts similarity index 100% rename from x-pack/plugins/apm/common/utils/formatters.test.ts rename to x-pack/plugins/apm/common/utils/formatters/formatters.test.ts diff --git a/x-pack/plugins/apm/public/utils/formatters/formatters.ts b/x-pack/plugins/apm/common/utils/formatters/formatters.ts similarity index 65% rename from x-pack/plugins/apm/public/utils/formatters/formatters.ts rename to x-pack/plugins/apm/common/utils/formatters/formatters.ts index 6249ce53b6779..649f11063b149 100644 --- a/x-pack/plugins/apm/public/utils/formatters/formatters.ts +++ b/x-pack/plugins/apm/common/utils/formatters/formatters.ts @@ -23,3 +23,24 @@ export function tpmUnit(type?: string) { defaultMessage: 'tpm', }); } + +export function asPercent( + numerator: number, + denominator: number | undefined, + fallbackResult = '' +) { + if (!denominator || isNaN(numerator)) { + return fallbackResult; + } + + const decimal = numerator / denominator; + + // 33.2 => 33% + // 3.32 => 3.3% + // 0 => 0% + if (Math.abs(decimal) >= 0.1 || decimal === 0) { + return numeral(decimal).format('0%'); + } + + return numeral(decimal).format('0.0%'); +} diff --git a/x-pack/plugins/apm/public/utils/formatters/index.ts b/x-pack/plugins/apm/common/utils/formatters/index.ts similarity index 100% rename from x-pack/plugins/apm/public/utils/formatters/index.ts rename to x-pack/plugins/apm/common/utils/formatters/index.ts diff --git a/x-pack/plugins/apm/public/utils/formatters/__test__/size.test.ts b/x-pack/plugins/apm/common/utils/formatters/size.test.ts similarity index 97% rename from x-pack/plugins/apm/public/utils/formatters/__test__/size.test.ts rename to x-pack/plugins/apm/common/utils/formatters/size.test.ts index 07d3d0c1eb08f..a394874fe6d87 100644 --- a/x-pack/plugins/apm/public/utils/formatters/__test__/size.test.ts +++ b/x-pack/plugins/apm/common/utils/formatters/size.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { getFixedByteFormatter, asDynamicBytes } from '../size'; +import { getFixedByteFormatter, asDynamicBytes } from './size'; describe('size formatters', () => { describe('byte formatting', () => { diff --git a/x-pack/plugins/apm/public/utils/formatters/size.ts b/x-pack/plugins/apm/common/utils/formatters/size.ts similarity index 100% rename from x-pack/plugins/apm/public/utils/formatters/size.ts rename to x-pack/plugins/apm/common/utils/formatters/size.ts diff --git a/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts b/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts index 14a50b7949f12..306c8e32ef6be 100644 --- a/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts +++ b/x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts @@ -26,12 +26,12 @@ export function registerApmAlerts( defaultActionMessage: i18n.translate( 'xpack.apm.alertTypes.errorCount.defaultActionMessage', { - defaultMessage: `\\{\\{alertName\\}\\} alert is firing for the following configuration: + defaultMessage: `\\{\\{alertName\\}\\} alert is firing because of the following conditions: - Service name: \\{\\{context.serviceName\\}\\} - Environment: \\{\\{context.environment\\}\\} -- Triggered value: \\{\\{context.triggerValue\\}\\} -- Threshold: \\{\\{context.threshold\\}\\}`, +- Threshold: \\{\\{context.threshold\\}\\} errors +- Triggered value: \\{\\{context.triggerValue\\}\\} errors over the last \\{\\{context.intervalSize\\}\\}\\{\\{context.intervalUnit\\}\\}`, } ), }); @@ -52,13 +52,13 @@ export function registerApmAlerts( defaultActionMessage: i18n.translate( 'xpack.apm.alertTypes.transactionDuration.defaultActionMessage', { - defaultMessage: `\\{\\{alertName\\}\\} alert is firing for the following configuration: + defaultMessage: `\\{\\{alertName\\}\\} alert is firing because of the following conditions: - Service name: \\{\\{context.serviceName\\}\\} - Type: \\{\\{context.transactionType\\}\\} - Environment: \\{\\{context.environment\\}\\} -- Triggered value: \\{\\{context.triggerValue\\}\\} -- Threshold: \\{\\{context.threshold\\}\\}`, +- Threshold: \\{\\{context.threshold\\}\\}ms +- Triggered value: \\{\\{context.triggerValue\\}\\} over the last \\{\\{context.intervalSize\\}\\}\\{\\{context.intervalUnit\\}\\}`, } ), }); @@ -79,13 +79,13 @@ export function registerApmAlerts( defaultActionMessage: i18n.translate( 'xpack.apm.alertTypes.transactionErrorRate.defaultActionMessage', { - defaultMessage: `\\{\\{alertName\\}\\} alert is firing for the following configuration: + defaultMessage: `\\{\\{alertName\\}\\} alert is firing because of the following conditions: - Service name: \\{\\{context.serviceName\\}\\} - Type: \\{\\{context.transactionType\\}\\} - Environment: \\{\\{context.environment\\}\\} -- Triggered value: \\{\\{context.triggerValue\\}\\} -- Threshold: \\{\\{context.threshold\\}\\}`, +- Threshold: \\{\\{context.threshold\\}\\}% +- Triggered value: \\{\\{context.triggerValue\\}\\}% of errors over the last \\{\\{context.intervalSize\\}\\}\\{\\{context.intervalUnit\\}\\}`, } ), }); @@ -106,12 +106,14 @@ export function registerApmAlerts( defaultActionMessage: i18n.translate( 'xpack.apm.alertTypes.transactionDurationAnomaly.defaultActionMessage', { - defaultMessage: `\\{\\{alertName\\}\\} alert is firing for the following configuration: + defaultMessage: `\\{\\{alertName\\}\\} alert is firing because of the following conditions: - Service name: \\{\\{context.serviceName\\}\\} - Type: \\{\\{context.transactionType\\}\\} - Environment: \\{\\{context.environment\\}\\} -- Threshold: \\{\\{context.threshold\\}\\}`, +- Severity threshold: \\{\\{context.threshold\\}\\} +- Severity value: \\{\\{context.thresholdValue\\}\\} +`, } ), }); diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx index 3b118bcd91ff1..e17dd9a9eb038 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx @@ -12,7 +12,7 @@ import d3 from 'd3'; import { scaleUtc } from 'd3-scale'; import { mean } from 'lodash'; import React from 'react'; -import { asRelativeDateTimeRange } from '../../../../utils/formatters'; +import { asRelativeDateTimeRange } from '../../../../../common/utils/formatters'; import { getTimezoneOffsetInMs } from '../../../shared/charts/CustomPlot/getTimezoneOffsetInMs'; // @ts-expect-error import Histogram from '../../../shared/charts/Histogram'; diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx index c1192f5f18274..3938349050e5e 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/AnomalyDetection.tsx @@ -20,7 +20,7 @@ import { } from '../../../../../common/service_health_status'; import { useTheme } from '../../../../hooks/useTheme'; import { fontSize, px } from '../../../../style/variables'; -import { asInteger, asDuration } from '../../../../utils/formatters'; +import { asInteger, asDuration } from '../../../../../common/utils/formatters'; import { MLJobLink } from '../../../shared/Links/MachineLearningLinks/MLJobLink'; import { popoverWidth } from '../cytoscapeOptions'; import { TRANSACTION_REQUEST } from '../../../../../common/transaction_types'; diff --git a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/ServiceStatsList.tsx b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/ServiceStatsList.tsx index ba4451c37b304..1628a664a6c27 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/ServiceStatsList.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceMap/Popover/ServiceStatsList.tsx @@ -8,9 +8,12 @@ import { i18n } from '@kbn/i18n'; import { isNumber } from 'lodash'; import React from 'react'; import styled from 'styled-components'; -import { asPercent } from '../../../../../common/utils/formatters'; +import { + asDuration, + asPercent, + tpmUnit, +} from '../../../../../common/utils/formatters'; import { ServiceNodeStats } from '../../../../../common/service_map'; -import { asDuration, tpmUnit } from '../../../../utils/formatters'; export const ItemRow = styled('tr')` line-height: 2; diff --git a/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx index 28477d2448899..02dc3934dd01e 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx @@ -13,7 +13,11 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import styled from 'styled-components'; -import { asPercent } from '../../../../common/utils/formatters'; +import { + asDynamicBytes, + asInteger, + asPercent, +} from '../../../../common/utils/formatters'; import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../common/i18n'; import { SERVICE_NODE_NAME_MISSING } from '../../../../common/service_nodes'; import { Projection } from '../../../../common/projections'; @@ -21,7 +25,6 @@ import { LocalUIFilters } from '../../shared/LocalUIFilters'; import { useUrlParams } from '../../../hooks/useUrlParams'; import { ManagedTable, ITableColumn } from '../../shared/ManagedTable'; import { useFetcher } from '../../../hooks/useFetcher'; -import { asDynamicBytes, asInteger } from '../../../utils/formatters'; import { ServiceNodeMetricOverviewLink } from '../../shared/Links/apm/ServiceNodeMetricOverviewLink'; import { truncate, px, unit } from '../../../style/variables'; diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx index 4c7c0824a7c49..aa0222582b891 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx @@ -11,12 +11,15 @@ import styled from 'styled-components'; import { ValuesType } from 'utility-types'; import { orderBy } from 'lodash'; import { ServiceHealthStatus } from '../../../../../common/service_health_status'; -import { asPercent } from '../../../../../common/utils/formatters'; +import { + asPercent, + asDecimal, + asMillisecondDuration, +} from '../../../../../common/utils/formatters'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ServiceListAPIResponse } from '../../../../../server/lib/services/get_services'; import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; import { fontSizes, px, truncate, unit } from '../../../../style/variables'; -import { asDecimal, asMillisecondDuration } from '../../../../utils/formatters'; import { ManagedTable, ITableColumn } from '../../../shared/ManagedTable'; import { EnvironmentBadge } from '../../../shared/EnvironmentBadge'; import { TransactionOverviewLink } from '../../../shared/Links/apm/TransactionOverviewLink'; diff --git a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx index cf2fe006f67d2..1c21824656754 100644 --- a/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx +++ b/x-pack/plugins/apm/public/components/app/TraceOverview/TraceList.tsx @@ -10,8 +10,8 @@ import React from 'react'; import styled from 'styled-components'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { TransactionGroup } from '../../../../server/lib/transaction_groups/fetcher'; +import { asMillisecondDuration } from '../../../../common/utils/formatters'; import { fontSizes, truncate } from '../../../style/variables'; -import { asMillisecondDuration } from '../../../utils/formatters'; import { EmptyMessage } from '../../shared/EmptyMessage'; import { ImpactBar } from '../../shared/ImpactBar'; import { ITableColumn, ManagedTable } from '../../shared/ManagedTable'; diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx index e18e6b1ed914e..67125d41635a9 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx @@ -10,12 +10,12 @@ import d3 from 'd3'; import { isEmpty } from 'lodash'; import React, { useCallback } from 'react'; import { ValuesType } from 'utility-types'; +import { getDurationFormatter } from '../../../../../common/utils/formatters'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { TransactionDistributionAPIResponse } from '../../../../../server/lib/transactions/distribution'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { DistributionBucket } from '../../../../../server/lib/transactions/distribution/get_buckets'; import { IUrlParams } from '../../../../context/UrlParamsContext/types'; -import { getDurationFormatter } from '../../../../utils/formatters'; // @ts-expect-error import Histogram from '../../../shared/charts/Histogram'; import { EmptyMessage } from '../../../shared/EmptyMessage'; diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/WaterfallItem.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/WaterfallItem.tsx index e1b5ffcd0e0f5..070f8a54446b3 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/WaterfallItem.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Waterfall/WaterfallItem.tsx @@ -9,9 +9,9 @@ import styled from 'styled-components'; import { EuiIcon, EuiText, EuiTitle, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { asDuration } from '../../../../../../../common/utils/formatters'; import { isRumAgentName } from '../../../../../../../common/agent_name'; import { px, unit, units } from '../../../../../../style/variables'; -import { asDuration } from '../../../../../../utils/formatters'; import { ErrorCount } from '../../ErrorCount'; import { IWaterfallItem } from './waterfall_helpers/waterfall_helpers'; import { ErrorOverviewLink } from '../../../../../shared/Links/apm/ErrorOverviewLink'; diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionList/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionList/index.tsx index 68f9c240f1562..7f1dd100d721c 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionList/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/TransactionList/index.tsx @@ -10,8 +10,11 @@ import React, { useMemo } from 'react'; import styled from 'styled-components'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { TransactionGroup } from '../../../../../server/lib/transaction_groups/fetcher'; +import { + asDecimal, + asMillisecondDuration, +} from '../../../../../common/utils/formatters'; import { fontFamilyCode, truncate } from '../../../../style/variables'; -import { asDecimal, asMillisecondDuration } from '../../../../utils/formatters'; import { ImpactBar } from '../../../shared/ImpactBar'; import { ITableColumn, ManagedTable } from '../../../shared/ManagedTable'; import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt'; diff --git a/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx b/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx index 7858bebead408..7e88ebc7639e3 100644 --- a/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx +++ b/x-pack/plugins/apm/public/components/shared/Summary/DurationSummaryItem.tsx @@ -6,8 +6,8 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiToolTip, EuiText } from '@elastic/eui'; +import { asDuration } from '../../../../common/utils/formatters'; import { PercentOfParent } from '../../app/TransactionDetails/WaterfallWithSummmary/PercentOfParent'; -import { asDuration } from '../../../utils/formatters'; interface Props { duration: number; diff --git a/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx b/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx index 504ff36c078f0..eaa291c33cff6 100644 --- a/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/TimestampTooltip/index.tsx @@ -6,7 +6,10 @@ import React from 'react'; import { EuiToolTip } from '@elastic/eui'; import moment from 'moment-timezone'; -import { asAbsoluteDateTime, TimeUnit } from '../../../utils/formatters'; +import { + asAbsoluteDateTime, + TimeUnit, +} from '../../../../common/utils/formatters'; interface Props { /** diff --git a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/AnnotationsPlot.tsx b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/AnnotationsPlot.tsx index d02c5a5d08927..9fc16ab0f9eab 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/AnnotationsPlot.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/AnnotationsPlot.tsx @@ -13,11 +13,11 @@ import { EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { asAbsoluteDateTime } from '../../../../../common/utils/formatters'; import { useTheme } from '../../../../hooks/useTheme'; import { Maybe } from '../../../../../typings/common'; import { Annotation } from '../../../../../common/annotations'; import { PlotValues, SharedPlot } from './plotUtils'; -import { asAbsoluteDateTime } from '../../../../utils/formatters'; interface Props { annotations: Annotation[]; diff --git a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js index be0716ba748dd..03fd039a3401e 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js +++ b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js @@ -9,16 +9,16 @@ import React from 'react'; import d3 from 'd3'; import { HistogramInner } from '../index'; import response from './response.json'; -import { - getDurationFormatter, - asInteger, -} from '../../../../../utils/formatters'; import { disableConsoleWarning, toJson, mountWithTheme, } from '../../../../../utils/testHelpers'; import { getFormattedBuckets } from '../../../../app/TransactionDetails/Distribution/index'; +import { + asInteger, + getDurationFormatter, +} from '../../../../../../common/utils/formatters'; describe('Histogram', () => { let mockConsole; diff --git a/x-pack/plugins/apm/public/components/shared/charts/MetricsChart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/MetricsChart/index.tsx index 3b77ef3b51403..270ebd1c0830d 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/MetricsChart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/MetricsChart/index.tsx @@ -5,18 +5,18 @@ */ import { EuiTitle } from '@elastic/eui'; import React from 'react'; -import { asPercent } from '../../../../../common/utils/formatters'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { GenericMetricsChart } from '../../../../../server/lib/metrics/transform_metrics_chart'; -// @ts-expect-error -import CustomPlot from '../CustomPlot'; import { + asPercent, asDecimal, asInteger, asDynamicBytes, getFixedByteFormatter, asDuration, -} from '../../../../utils/formatters'; +} from '../../../../../common/utils/formatters'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { GenericMetricsChart } from '../../../../../server/lib/metrics/transform_metrics_chart'; +// @ts-expect-error +import CustomPlot from '../CustomPlot'; import { Coordinate } from '../../../../../typings/timeseries'; import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; import { useChartsSync } from '../../../../hooks/useChartsSync'; diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/AgentMarker.tsx b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/AgentMarker.tsx index 64e0fe33c982f..37d3664e98acd 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/AgentMarker.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/AgentMarker.tsx @@ -7,9 +7,9 @@ import React from 'react'; import { EuiToolTip } from '@elastic/eui'; import styled from 'styled-components'; +import { asDuration } from '../../../../../../common/utils/formatters'; import { useTheme } from '../../../../../hooks/useTheme'; import { px, units } from '../../../../../style/variables'; -import { asDuration } from '../../../../../utils/formatters'; import { Legend } from '../../Legend'; import { AgentMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_agent_marks'; diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.tsx b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.tsx index 4567bc3f0f0b7..de63e2323ddac 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.tsx @@ -7,6 +7,7 @@ import React, { useState } from 'react'; import { EuiPopover, EuiText } from '@elastic/eui'; import styled from 'styled-components'; +import { asDuration } from '../../../../../../common/utils/formatters'; import { useTheme } from '../../../../../hooks/useTheme'; import { TRACE_ID, @@ -14,7 +15,6 @@ import { } from '../../../../../../common/elasticsearch_fieldnames'; import { useUrlParams } from '../../../../../hooks/useUrlParams'; import { px, unit, units } from '../../../../../style/variables'; -import { asDuration } from '../../../../../utils/formatters'; import { ErrorMark } from '../../../../app/TransactionDetails/WaterfallWithSummmary/WaterfallContainer/Marks/get_error_marks'; import { ErrorDetailLink } from '../../../Links/apm/ErrorDetailLink'; import { Legend, Shape } from '../../Legend'; diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/TimelineAxis.tsx b/x-pack/plugins/apm/public/components/shared/charts/Timeline/TimelineAxis.tsx index 5cbfcc695e012..cb5a44432dcbc 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/TimelineAxis.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/Timeline/TimelineAxis.tsx @@ -8,9 +8,9 @@ import React, { ReactNode } from 'react'; import { inRange } from 'lodash'; import { Sticky } from 'react-sticky'; import { XAxis, XYPlot } from 'react-vis'; +import { getDurationFormatter } from '../../../../../common/utils/formatters'; import { useTheme } from '../../../../hooks/useTheme'; import { px } from '../../../../style/variables'; -import { getDurationFormatter } from '../../../../utils/formatters'; import { Mark } from './'; import { LastTickValue } from './LastTickValue'; import { Marker } from './Marker'; diff --git a/x-pack/plugins/apm/public/components/shared/charts/Tooltip/index.js b/x-pack/plugins/apm/public/components/shared/charts/Tooltip/index.js index 7ee0c6280526b..7183c4851e993 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Tooltip/index.js +++ b/x-pack/plugins/apm/public/components/shared/charts/Tooltip/index.js @@ -18,7 +18,7 @@ import { fontSizes, } from '../../../../style/variables'; import { Legend } from '../Legend'; -import { asAbsoluteDateTime } from '../../../../utils/formatters'; +import { asAbsoluteDateTime } from '../../../../../common/utils/formatters'; const TooltipElm = styled.div` margin: 0 ${px(unit)}; diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts index a476892fa4a3f..850e5d9a16112 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.test.ts @@ -9,11 +9,12 @@ import { getResponseTimeTooltipFormatter, getMaxY, } from './helper'; + +import { TimeSeries } from '../../../../../typings/timeseries'; import { getDurationFormatter, toMicroseconds, -} from '../../../../utils/formatters'; -import { TimeSeries } from '../../../../../typings/timeseries'; +} from '../../../../../common/utils/formatters'; describe('transaction chart helper', () => { describe('getResponseTimeTickFormatter', () => { diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx index f11a33f932553..db245792982c3 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/helper.tsx @@ -5,10 +5,10 @@ */ import { flatten } from 'lodash'; +import { TimeFormatter } from '../../../../../common/utils/formatters'; import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; import { TimeSeries, Coordinate } from '../../../../../typings/timeseries'; -import { TimeFormatter } from '../../../../utils/formatters'; export function getResponseTimeTickFormatter(formatter: TimeFormatter) { return (t: number) => { diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx index 30ee0ba3eaa1f..0b741447f6fec 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx @@ -24,7 +24,7 @@ import { Coordinate } from '../../../../../typings/timeseries'; import { LicenseContext } from '../../../../context/LicenseContext'; import { IUrlParams } from '../../../../context/UrlParamsContext/types'; import { ITransactionChartData } from '../../../../selectors/chartSelectors'; -import { asDecimal, tpmUnit } from '../../../../utils/formatters'; +import { asDecimal, tpmUnit } from '../../../../../common/utils/formatters'; import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue'; import { ErroneousTransactionsRateChart } from '../ErroneousTransactionsRateChart'; import { TransactionBreakdown } from '../../TransactionBreakdown'; diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.test.tsx index 78ff9a398b2e7..fc873cbda7bf2 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.test.tsx @@ -5,9 +5,9 @@ */ import React from 'react'; import { TimeSeries } from '../../../../../typings/timeseries'; -import { toMicroseconds } from '../../../../utils/formatters'; import { useFormatter } from './use_formatter'; import { render, fireEvent, act } from '@testing-library/react'; +import { toMicroseconds } from '../../../../../common/utils/formatters'; function MockComponent({ timeSeries, diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.ts b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.ts index 8cd8929c89960..d4694bc3caf1d 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/use_formatter.ts @@ -9,7 +9,7 @@ import { isEmpty } from 'lodash'; import { getDurationFormatter, TimeFormatter, -} from '../../../../utils/formatters'; +} from '../../../../../common/utils/formatters'; import { TimeSeries } from '../../../../../typings/timeseries'; import { getMaxY } from './helper'; diff --git a/x-pack/plugins/apm/public/selectors/chartSelectors.ts b/x-pack/plugins/apm/public/selectors/chartSelectors.ts index 26c2365ed77e1..8c6093859f969 100644 --- a/x-pack/plugins/apm/public/selectors/chartSelectors.ts +++ b/x-pack/plugins/apm/public/selectors/chartSelectors.ts @@ -17,10 +17,10 @@ import { RectCoordinate, TimeSeries, } from '../../typings/timeseries'; -import { asDecimal, asDuration, tpmUnit } from '../utils/formatters'; import { IUrlParams } from '../context/UrlParamsContext/types'; import { getEmptySeries } from '../components/shared/charts/CustomPlot/getEmptySeries'; import { httpStatusCodeToColor } from '../utils/httpStatusCodeToColor'; +import { asDecimal, asDuration, tpmUnit } from '../../common/utils/formatters'; export interface ITpmBucket { title: string; diff --git a/x-pack/plugins/apm/server/lib/alerts/action_variables.ts b/x-pack/plugins/apm/server/lib/alerts/action_variables.ts index f2558da3a30e4..6361279b3437c 100644 --- a/x-pack/plugins/apm/server/lib/alerts/action_variables.ts +++ b/x-pack/plugins/apm/server/lib/alerts/action_variables.ts @@ -45,4 +45,24 @@ export const apmActionVariables = { ), name: 'triggerValue', }, + windowSize: { + description: i18n.translate( + 'xpack.apm.alerts.action_variables.intervalSize', + { + defaultMessage: + 'The interval size the alert will use to check for any incident', + } + ), + name: 'intervalSize', + }, + windowUnit: { + description: i18n.translate( + 'xpack.apm.alerts.action_variables.intervalUnit', + { + defaultMessage: + 'The interval unit the alert will use to check for any incident', + } + ), + name: 'intervalUnit', + }, }; diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.test.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.test.ts index 6a6e2b7137055..ca121a40d4d32 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.test.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.test.ts @@ -100,7 +100,7 @@ describe('Error count alert', () => { })), alertInstanceFactory: jest.fn(() => ({ scheduleActions })), }; - const params = { threshold: 1 }; + const params = { threshold: 1, windowSize: 5, windowUnit: 'm' }; await alertExecutor!({ services, params }); [ @@ -117,24 +117,32 @@ describe('Error count alert', () => { environment: 'env-foo', threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'foo', environment: 'env-foo-2', threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', environment: 'env-bar', threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', environment: 'env-bar-2', threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); }); it('sends alerts with service name', async () => { @@ -174,7 +182,7 @@ describe('Error count alert', () => { })), alertInstanceFactory: jest.fn(() => ({ scheduleActions })), }; - const params = { threshold: 1 }; + const params = { threshold: 1, windowSize: 5, windowUnit: 'm' }; await alertExecutor!({ services, params }); ['apm.error_rate_foo', 'apm.error_rate_bar'].forEach((instanceName) => @@ -186,12 +194,16 @@ describe('Error count alert', () => { environment: undefined, threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', environment: undefined, threshold: 1, triggerValue: 2, + intervalSize: 5, + intervalUnit: 'm', }); }); }); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts index 26e4a5e84b995..20fbd3db25f4e 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_error_count_alert_type.ts @@ -55,6 +55,8 @@ export function registerErrorCountAlertType({ apmActionVariables.environment, apmActionVariables.threshold, apmActionVariables.triggerValue, + apmActionVariables.windowSize, + apmActionVariables.windowUnit, ], }, producer: 'apm', @@ -138,6 +140,8 @@ export function registerErrorCountAlertType({ environment, threshold: alertParams.threshold, triggerValue: errorCount, + intervalSize: alertParams.windowSize, + intervalUnit: alertParams.windowUnit, }); } response.aggregations?.services.buckets.forEach((serviceBucket) => { diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts index 373d4bd4da832..57201b3f267f1 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; +import { getDurationFormatter } from '../../../common/utils/formatters'; import { ProcessorEvent } from '../../../common/processor_event'; import { AlertType, ALERT_TYPES_CONFIG } from '../../../common/alert_types'; import { ESSearchResponse } from '../../../typings/elasticsearch'; @@ -15,6 +16,7 @@ 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'; @@ -62,6 +64,8 @@ export function registerTransactionDurationAlertType({ apmActionVariables.environment, apmActionVariables.threshold, apmActionVariables.triggerValue, + apmActionVariables.windowSize, + apmActionVariables.windowUnit, ], }, producer: 'apm', @@ -106,6 +110,11 @@ export function registerTransactionDurationAlertType({ ], }, }, + environments: { + terms: { + field: SERVICE_ENVIRONMENT, + }, + }, }, }, }; @@ -119,7 +128,7 @@ export function registerTransactionDurationAlertType({ return; } - const { agg } = response.aggregations; + const { agg, environments } = response.aggregations; const transactionDuration = 'values' in agg ? Object.values(agg.values)[0] : agg?.value; @@ -127,15 +136,26 @@ export function registerTransactionDurationAlertType({ 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, + const durationFormatter = getDurationFormatter(transactionDuration); + const transactionDurationFormatted = durationFormatter( + transactionDuration + ).formatted; + + environments.buckets.map((bucket) => { + const environment = bucket.key; + const alertInstance = services.alertInstanceFactory( + `${AlertType.TransactionDuration}_${environment}` + ); + + alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, { + transactionType: alertParams.transactionType, + serviceName: alertParams.serviceName, + environment, + threshold, + triggerValue: transactionDurationFormatted, + intervalSize: alertParams.windowSize, + intervalUnit: alertParams.windowUnit, + }); }); } }, diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.test.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.test.ts index c66dbdde14a57..17f6bb3ac19cf 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.test.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.test.ts @@ -180,12 +180,14 @@ describe('Transaction duration anomaly alert', () => { transaction_types: { buckets: [{ key: 'type-foo' }], }, + record_avg: { value: 80 }, }, { key: 'bar', transaction_types: { buckets: [{ key: 'type-bar' }], }, + record_avg: { value: 20 }, }, ], }, @@ -224,12 +226,14 @@ describe('Transaction duration anomaly alert', () => { transactionType: 'type-foo', environment: 'production', threshold: 'minor', + thresholdValue: 'critical', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: 'type-bar', environment: 'production', threshold: 'minor', + thresholdValue: 'warning', }); }); @@ -269,7 +273,10 @@ describe('Transaction duration anomaly alert', () => { hits: { total: { value: 2 } }, aggregations: { services: { - buckets: [{ key: 'foo' }, { key: 'bar' }], + buckets: [ + { key: 'foo', record_avg: { value: 80 } }, + { key: 'bar', record_avg: { value: 20 } }, + ], }, }, }), @@ -308,24 +315,28 @@ describe('Transaction duration anomaly alert', () => { transactionType: undefined, environment: 'production', threshold: 'minor', + thresholdValue: 'critical', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: undefined, environment: 'production', threshold: 'minor', + thresholdValue: 'warning', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'foo', transactionType: undefined, environment: 'testing', threshold: 'minor', + thresholdValue: 'critical', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: undefined, environment: 'testing', threshold: 'minor', + thresholdValue: 'warning', }); }); }); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts index 3a2de78cc0677..9b3da56b6f640 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_anomaly_alert_type.ts @@ -7,6 +7,7 @@ import { schema } from '@kbn/config-schema'; import { Observable } from 'rxjs'; import { isEmpty } from 'lodash'; +import { getSeverity } from '../../../common/anomaly_detection'; import { ANOMALY_SEVERITY } from '../../../../ml/common'; import { KibanaRequest } from '../../../../../../src/core/server'; import { @@ -62,6 +63,7 @@ export function registerTransactionDurationAnomalyAlertType({ apmActionVariables.transactionType, apmActionVariables.environment, apmActionVariables.threshold, + apmActionVariables.triggerValue, ], }, producer: 'apm', @@ -149,6 +151,11 @@ export function registerTransactionDurationAnomalyAlertType({ field: 'by_field_value', }, }, + record_avg: { + avg: { + field: 'record_score', + }, + }, }, }, }, @@ -163,6 +170,7 @@ export function registerTransactionDurationAnomalyAlertType({ services: { buckets: Array<{ key: string; + record_avg: { value: number }; transaction_types: { buckets: Array<{ key: string }> }; }>; }; @@ -174,10 +182,12 @@ export function registerTransactionDurationAnomalyAlertType({ if (hitCount > 0) { function scheduleAction({ serviceName, + severity, environment, transactionType, }: { serviceName: string; + severity: string; environment?: string; transactionType?: string; }) { @@ -193,24 +203,31 @@ export function registerTransactionDurationAnomalyAlertType({ const alertInstance = services.alertInstanceFactory( alertInstanceName ); + alertInstance.scheduleActions(alertTypeConfig.defaultActionGroupId, { serviceName, environment, transactionType, threshold: selectedOption?.label, + thresholdValue: severity, }); } - mlJobs.map((job) => { const environment = job.custom_settings?.job_tags?.environment; response.aggregations?.services.buckets.forEach((serviceBucket) => { const serviceName = serviceBucket.key as string; + const severity = getSeverity(serviceBucket.record_avg.value); if (isEmpty(serviceBucket.transaction_types?.buckets)) { - scheduleAction({ serviceName, environment }); + scheduleAction({ serviceName, severity, environment }); } else { serviceBucket.transaction_types?.buckets.forEach((typeBucket) => { const transactionType = typeBucket.key as string; - scheduleAction({ serviceName, environment, transactionType }); + scheduleAction({ + serviceName, + severity, + environment, + transactionType, + }); }); } }); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.test.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.test.ts index 90db48f84b5d9..207e6108cd83c 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.test.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.test.ts @@ -115,7 +115,7 @@ describe('Transaction error rate alert', () => { })), alertInstanceFactory: jest.fn(() => ({ scheduleActions })), }; - const params = { threshold: 10 }; + const params = { threshold: 10, windowSize: 5, windowUnit: 'm' }; await alertExecutor!({ services, params }); [ @@ -132,28 +132,36 @@ describe('Transaction error rate alert', () => { transactionType: 'type-foo', environment: 'env-foo', threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'foo', transactionType: 'type-foo', environment: 'env-foo-2', threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: 'type-bar', environment: 'env-bar', threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: 'type-bar', environment: 'env-bar-2', threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); }); it('sends alerts with service name and transaction type', async () => { @@ -202,7 +210,7 @@ describe('Transaction error rate alert', () => { })), alertInstanceFactory: jest.fn(() => ({ scheduleActions })), }; - const params = { threshold: 10 }; + const params = { threshold: 10, windowSize: 5, windowUnit: 'm' }; await alertExecutor!({ services, params }); [ @@ -217,14 +225,18 @@ describe('Transaction error rate alert', () => { transactionType: 'type-foo', environment: undefined, threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: 'type-bar', environment: undefined, threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); }); @@ -261,7 +273,7 @@ describe('Transaction error rate alert', () => { })), alertInstanceFactory: jest.fn(() => ({ scheduleActions })), }; - const params = { threshold: 10 }; + const params = { threshold: 10, windowSize: 5, windowUnit: 'm' }; await alertExecutor!({ services, params }); [ @@ -276,14 +288,18 @@ describe('Transaction error rate alert', () => { transactionType: undefined, environment: undefined, threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); expect(scheduleActions).toHaveBeenCalledWith('threshold_met', { serviceName: 'bar', transactionType: undefined, environment: undefined, threshold: 10, - triggerValue: 50, + triggerValue: '50', + intervalSize: 5, + intervalUnit: 'm', }); }); }); diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts index e14360029e5dd..26a23e33f8730 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts @@ -60,6 +60,8 @@ export function registerTransactionErrorRateAlertType({ apmActionVariables.environment, apmActionVariables.threshold, apmActionVariables.triggerValue, + apmActionVariables.windowSize, + apmActionVariables.windowUnit, ], }, producer: 'apm', @@ -170,7 +172,11 @@ export function registerTransactionErrorRateAlertType({ transactionType, environment, threshold: alertParams.threshold, - triggerValue: transactionErrorRate, + triggerValue: String( + parseFloat(transactionErrorRate.toPrecision(3)) + ), + intervalSize: alertParams.windowSize, + intervalUnit: alertParams.windowUnit, }); }