mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[APM] Add error grouping key filter in error count rule type (#155410)
part of https://github.com/elastic/kibana/issues/152329 Introduces the error grouping key filter in the error count rule type https://user-images.githubusercontent.com/3369346/233397481-899e32e0-f26d-4335-84fe-e18c5264f3d2.mov
This commit is contained in:
parent
656f824a61
commit
d401b44288
8 changed files with 107 additions and 3 deletions
|
@ -15,6 +15,7 @@ export const errorCountParamsSchema = schema.object({
|
|||
threshold: schema.number(),
|
||||
serviceName: schema.maybe(schema.string()),
|
||||
environment: schema.string(),
|
||||
errorGroupingKey: schema.maybe(schema.string()),
|
||||
});
|
||||
|
||||
export const transactionDurationParamsSchema = schema.object({
|
||||
|
|
|
@ -21,6 +21,7 @@ import { createCallApmApi } from '../../../../services/rest/create_call_apm_api'
|
|||
import { ChartPreview } from '../../ui_components/chart_preview';
|
||||
import {
|
||||
EnvironmentField,
|
||||
ErrorGroupingKeyField,
|
||||
IsAboveField,
|
||||
ServiceField,
|
||||
} from '../../utils/fields';
|
||||
|
@ -33,6 +34,7 @@ export interface RuleParams {
|
|||
threshold?: number;
|
||||
serviceName?: string;
|
||||
environment?: string;
|
||||
errorGroupingKey?: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
|
@ -74,6 +76,7 @@ export function ErrorCountRuleType(props: Props) {
|
|||
query: {
|
||||
environment: params.environment,
|
||||
serviceName: params.serviceName,
|
||||
errorGroupingKey: params.errorGroupingKey,
|
||||
interval,
|
||||
start,
|
||||
end,
|
||||
|
@ -88,6 +91,7 @@ export function ErrorCountRuleType(props: Props) {
|
|||
params.windowUnit,
|
||||
params.environment,
|
||||
params.serviceName,
|
||||
params.errorGroupingKey,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -98,6 +102,7 @@ export function ErrorCountRuleType(props: Props) {
|
|||
if (value !== params.serviceName) {
|
||||
setRuleParams('serviceName', value);
|
||||
setRuleParams('environment', ENVIRONMENT_ALL.value);
|
||||
setRuleParams('errorGroupingKey', undefined);
|
||||
}
|
||||
}}
|
||||
/>,
|
||||
|
@ -106,6 +111,12 @@ export function ErrorCountRuleType(props: Props) {
|
|||
onChange={(value) => setRuleParams('environment', value)}
|
||||
serviceName={params.serviceName}
|
||||
/>,
|
||||
<ErrorGroupingKeyField
|
||||
currentValue={params.errorGroupingKey}
|
||||
onChange={(value) => setRuleParams('errorGroupingKey', value)}
|
||||
serviceName={params.serviceName}
|
||||
/>,
|
||||
|
||||
<IsAboveField
|
||||
value={params.threshold}
|
||||
unit={i18n.translate('xpack.apm.errorCountRuleType.errors', {
|
||||
|
|
|
@ -9,6 +9,7 @@ import { EuiFieldNumber } from '@elastic/eui';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import {
|
||||
ERROR_GROUP_ID,
|
||||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_NAME,
|
||||
TRANSACTION_TYPE,
|
||||
|
@ -178,6 +179,45 @@ export function TransactionTypeField({
|
|||
);
|
||||
}
|
||||
|
||||
export function ErrorGroupingKeyField({
|
||||
currentValue,
|
||||
onChange,
|
||||
serviceName,
|
||||
}: {
|
||||
currentValue?: string;
|
||||
onChange: (value?: string) => void;
|
||||
serviceName?: string;
|
||||
}) {
|
||||
const label = i18n.translate('xpack.apm.alerting.fields.error.group.id', {
|
||||
defaultMessage: 'Error grouping key',
|
||||
});
|
||||
return (
|
||||
<PopoverExpression value={currentValue || allOptionText} title={label}>
|
||||
<SuggestionsSelect
|
||||
customOptions={[{ label: allOptionText, value: undefined }]}
|
||||
customOptionText={i18n.translate(
|
||||
'xpack.apm.errorKeySelectCustomOptionText',
|
||||
{
|
||||
defaultMessage: 'Add \\{searchValue\\} as a new error grouping key',
|
||||
}
|
||||
)}
|
||||
defaultValue={currentValue}
|
||||
fieldName={ERROR_GROUP_ID}
|
||||
onChange={onChange}
|
||||
placeholder={i18n.translate(
|
||||
'xpack.apm.errorGroupingKeySelectPlaceholder',
|
||||
{
|
||||
defaultMessage: 'Select error grouping key',
|
||||
}
|
||||
)}
|
||||
start={moment().subtract(24, 'h').toISOString()}
|
||||
end={moment().toISOString()}
|
||||
serviceName={serviceName}
|
||||
/>
|
||||
</PopoverExpression>
|
||||
);
|
||||
}
|
||||
|
||||
export function IsAboveField({
|
||||
value,
|
||||
unit,
|
||||
|
|
|
@ -94,4 +94,13 @@ export const apmActionVariables = {
|
|||
name: 'viewInAppUrl' as const,
|
||||
usesPublicBaseUrl: true,
|
||||
},
|
||||
errorGroupingKey: {
|
||||
description: i18n.translate(
|
||||
'xpack.apm.alerts.action_variables.errorGroupingKey',
|
||||
{
|
||||
defaultMessage: 'The error grouping key the alert is created for',
|
||||
}
|
||||
),
|
||||
name: 'errorGroupingKey' as const,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@ const alertParamsRt = t.intersection([
|
|||
t.literal(AggregationType.P99),
|
||||
]),
|
||||
serviceName: t.string,
|
||||
errorGroupingKey: t.string,
|
||||
transactionType: t.string,
|
||||
transactionName: t.string,
|
||||
}),
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
|
||||
import { rangeQuery, termQuery } from '@kbn/observability-plugin/server';
|
||||
import { ProcessorEvent } from '@kbn/observability-plugin/common';
|
||||
import { SERVICE_NAME } from '../../../../../common/es_fields/apm';
|
||||
import {
|
||||
ERROR_GROUP_ID,
|
||||
SERVICE_NAME,
|
||||
} from '../../../../../common/es_fields/apm';
|
||||
import { AlertParams } from '../../route';
|
||||
import { environmentQuery } from '../../../../../common/utils/environment_query';
|
||||
import { APMEventClient } from '../../../../lib/helpers/create_es_client/create_apm_event_client';
|
||||
|
@ -24,12 +27,14 @@ export async function getTransactionErrorCountChartPreview({
|
|||
apmEventClient: APMEventClient;
|
||||
alertParams: AlertParams;
|
||||
}): Promise<TransactionErrorCountChartPreviewResponse> {
|
||||
const { serviceName, environment, interval, start, end } = alertParams;
|
||||
const { serviceName, environment, errorGroupingKey, interval, start, end } =
|
||||
alertParams;
|
||||
|
||||
const query = {
|
||||
bool: {
|
||||
filter: [
|
||||
...termQuery(SERVICE_NAME, serviceName),
|
||||
...termQuery(ERROR_GROUP_ID, errorGroupingKey),
|
||||
...rangeQuery(start, end),
|
||||
...environmentQuery(environment),
|
||||
],
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
getEnvironmentLabel,
|
||||
} from '../../../../../common/environment_filter_values';
|
||||
import {
|
||||
ERROR_GROUP_ID,
|
||||
PROCESSOR_EVENT,
|
||||
SERVICE_ENVIRONMENT,
|
||||
SERVICE_NAME,
|
||||
|
@ -77,6 +78,7 @@ export function registerErrorCountRuleType({
|
|||
apmActionVariables.interval,
|
||||
apmActionVariables.reason,
|
||||
apmActionVariables.serviceName,
|
||||
apmActionVariables.errorGroupingKey,
|
||||
apmActionVariables.threshold,
|
||||
apmActionVariables.triggerValue,
|
||||
apmActionVariables.viewInAppUrl,
|
||||
|
@ -112,6 +114,7 @@ export function registerErrorCountRuleType({
|
|||
},
|
||||
{ term: { [PROCESSOR_EVENT]: ProcessorEvent.error } },
|
||||
...termQuery(SERVICE_NAME, ruleParams.serviceName),
|
||||
...termQuery(ERROR_GROUP_ID, ruleParams.errorGroupingKey),
|
||||
...environmentQuery(ruleParams.environment),
|
||||
],
|
||||
},
|
||||
|
@ -164,7 +167,12 @@ export function registerErrorCountRuleType({
|
|||
windowUnit: ruleParams.windowUnit,
|
||||
});
|
||||
|
||||
const id = [ApmRuleType.ErrorCount, serviceName, environment]
|
||||
const id = [
|
||||
ApmRuleType.ErrorCount,
|
||||
serviceName,
|
||||
environment,
|
||||
ruleParams.errorGroupingKey,
|
||||
]
|
||||
.filter((name) => name)
|
||||
.join('_');
|
||||
|
||||
|
@ -188,6 +196,7 @@ export function registerErrorCountRuleType({
|
|||
[PROCESSOR_EVENT]: ProcessorEvent.error,
|
||||
[ALERT_EVALUATION_VALUE]: errorCount,
|
||||
[ALERT_EVALUATION_THRESHOLD]: ruleParams.threshold,
|
||||
[ERROR_GROUP_ID]: ruleParams.errorGroupingKey,
|
||||
[ALERT_REASON]: alertReason,
|
||||
...sourceFields,
|
||||
},
|
||||
|
@ -201,6 +210,7 @@ export function registerErrorCountRuleType({
|
|||
reason: alertReason,
|
||||
serviceName,
|
||||
threshold: ruleParams.threshold,
|
||||
errorGroupingKey: ruleParams.errorGroupingKey,
|
||||
triggerValue: errorCount,
|
||||
viewInAppUrl,
|
||||
});
|
||||
|
|
|
@ -100,6 +100,33 @@ export default function ApiTest({ getService }: FtrProviderContext) {
|
|||
).to.equal(true);
|
||||
});
|
||||
|
||||
it('error_count with error grouping key', async () => {
|
||||
const options = {
|
||||
params: {
|
||||
query: {
|
||||
start,
|
||||
end,
|
||||
serviceName: 'opbeans-java',
|
||||
errorGroupingKey: 'd16d39e7fa133b8943cea035430a7b4e',
|
||||
environment: 'ENVIRONMENT_ALL',
|
||||
interval: '5m',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const response = await apmApiClient.readUser({
|
||||
endpoint: 'GET /internal/apm/rule_types/error_count/chart_preview',
|
||||
...options,
|
||||
});
|
||||
|
||||
expect(response.status).to.be(200);
|
||||
expect(response.body.errorCountChartPreview).to.eql([
|
||||
{ x: 1627974600000, y: 4 },
|
||||
{ x: 1627974900000, y: 2 },
|
||||
{ x: 1627975200000, y: 0 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('transaction_duration (with data)', async () => {
|
||||
const options = getOptions();
|
||||
const response = await apmApiClient.readUser({
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue