mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
[AO] Add integration test for the Threshold Rule (#160633)
## Summary It fixes #160510 by: - Adding integration tests for the Threshold Rule. - Update the consumer value. - Update the action group.
This commit is contained in:
parent
73d1ed4ef8
commit
2b45cf628f
11 changed files with 439 additions and 15 deletions
|
@ -8,9 +8,9 @@
|
|||
import * as rt from 'io-ts';
|
||||
import { ML_ANOMALY_THRESHOLD } from '@kbn/ml-anomaly-utils/anomaly_threshold';
|
||||
import { values } from 'lodash';
|
||||
import { SerializedSearchSourceFields } from '@kbn/data-plugin/common';
|
||||
import { Color } from './color_palette';
|
||||
import { metricsExplorerMetricRT } from './metrics_explorer';
|
||||
|
||||
import { TimeUnitChar } from '../utils/formatters/duration';
|
||||
import { SNAPSHOT_CUSTOM_AGGREGATIONS } from './constants';
|
||||
|
||||
|
@ -201,13 +201,14 @@ export interface MetricAnomalyParams {
|
|||
|
||||
// Types for the executor
|
||||
|
||||
export interface MetricThresholdParams {
|
||||
export interface ThresholdParams {
|
||||
criteria: MetricExpressionParams[];
|
||||
filterQuery?: string;
|
||||
filterQueryText?: string;
|
||||
sourceId?: string;
|
||||
alertOnNoData?: boolean;
|
||||
alertOnGroupDisappear?: boolean;
|
||||
searchConfiguration: SerializedSearchSourceFields;
|
||||
}
|
||||
|
||||
interface BaseMetricExpressionParams {
|
||||
|
|
|
@ -28,7 +28,7 @@ export function AlertFlyout(props: Props) {
|
|||
() =>
|
||||
triggersActionsUI &&
|
||||
triggersActionsUI.getAddRuleFlyout({
|
||||
consumer: 'infrastructure',
|
||||
consumer: 'alerts',
|
||||
onClose: onCloseFlyout,
|
||||
canChangeTrigger: false,
|
||||
ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID,
|
||||
|
|
|
@ -71,8 +71,8 @@ export type MetricThresholdAlertContext = {
|
|||
value?: Record<string, unknown> | null;
|
||||
};
|
||||
|
||||
export const FIRED_ACTIONS_ID = 'metrics.threshold.fired';
|
||||
export const NO_DATA_ACTIONS_ID = 'metrics.threshold.nodata';
|
||||
export const FIRED_ACTIONS_ID = 'threshold.fired';
|
||||
export const NO_DATA_ACTIONS_ID = 'threshold.nodata';
|
||||
|
||||
type MetricThresholdActionGroup =
|
||||
| typeof FIRED_ACTIONS_ID
|
||||
|
@ -408,14 +408,14 @@ export const createMetricThresholdExecutor = ({
|
|||
};
|
||||
|
||||
export const FIRED_ACTIONS = {
|
||||
id: 'metrics.threshold.fired',
|
||||
id: 'threshold.fired',
|
||||
name: i18n.translate('xpack.observability.threshold.rule.alerting.threshold.fired', {
|
||||
defaultMessage: 'Alert',
|
||||
}),
|
||||
};
|
||||
|
||||
export const NO_DATA_ACTIONS = {
|
||||
id: 'metrics.threshold.nodata',
|
||||
id: 'threshold.nodata',
|
||||
name: i18n.translate('xpack.observability.threshold.rule.alerting.threshold.nodata', {
|
||||
defaultMessage: 'No Data',
|
||||
}),
|
||||
|
|
|
@ -185,6 +185,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions)
|
|||
'--xpack.alerting.healthCheck.interval="1s"',
|
||||
'--xpack.alerting.rules.minimumScheduleInterval.value="1s"',
|
||||
'--xpack.alerting.rules.run.alerts.max=20',
|
||||
'--xpack.observability.unsafe.thresholdRule.enabled=true',
|
||||
`--xpack.alerting.rules.run.actions.connectorTypeOverrides=${JSON.stringify([
|
||||
{ id: 'test.capped', max: '1' },
|
||||
])}`,
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { InfraRuleType, InfraRuleTypeParams } from '@kbn/infra-plugin/common/alerting/metrics';
|
||||
import { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics';
|
||||
import { ThresholdParams } from '@kbn/observability-plugin/common/threshold_rule/types';
|
||||
import type { SuperTest, Test } from 'supertest';
|
||||
|
||||
export async function createIndexConnector({
|
||||
|
@ -31,31 +32,35 @@ export async function createIndexConnector({
|
|||
return body.id as string;
|
||||
}
|
||||
|
||||
export async function createMetricThresholdRule<T extends InfraRuleType>({
|
||||
export async function createRule({
|
||||
supertest,
|
||||
name,
|
||||
ruleTypeId,
|
||||
params,
|
||||
actions = [],
|
||||
tags = [],
|
||||
schedule,
|
||||
consumer,
|
||||
}: {
|
||||
supertest: SuperTest<Test>;
|
||||
ruleTypeId: T;
|
||||
ruleTypeId: string;
|
||||
name: string;
|
||||
params: InfraRuleTypeParams[T];
|
||||
params: MetricThresholdParams | ThresholdParams;
|
||||
actions?: any[];
|
||||
tags?: any[];
|
||||
schedule?: { interval: string };
|
||||
consumer: string;
|
||||
}) {
|
||||
const { body } = await supertest
|
||||
.post(`/api/alerting/rule`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
params,
|
||||
consumer: 'infrastructure',
|
||||
consumer,
|
||||
schedule: schedule || {
|
||||
interval: '5m',
|
||||
},
|
||||
tags: ['infrastructure'],
|
||||
tags,
|
||||
name,
|
||||
rule_type_id: ruleTypeId,
|
||||
actions,
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { SuperTest, Test } from 'supertest';
|
||||
|
||||
export const createDataView = async ({
|
||||
supertest,
|
||||
id,
|
||||
name,
|
||||
title,
|
||||
}: {
|
||||
supertest: SuperTest<Test>;
|
||||
id: string;
|
||||
name: string;
|
||||
title: string;
|
||||
}) => {
|
||||
const { body } = await supertest
|
||||
.post(`/api/content_management/rpc/create`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
contentTypeId: 'index-pattern',
|
||||
data: {
|
||||
fieldAttrs: '{}',
|
||||
title,
|
||||
timeFieldName: '@timestamp',
|
||||
sourceFilters: '[]',
|
||||
fields: '[]',
|
||||
fieldFormatMap: '{}',
|
||||
typeMeta: '{}',
|
||||
runtimeFieldMap: '{}',
|
||||
name,
|
||||
},
|
||||
options: { id },
|
||||
version: 1,
|
||||
});
|
||||
return body;
|
||||
};
|
||||
export const deleteDataView = async ({
|
||||
supertest,
|
||||
id,
|
||||
}: {
|
||||
supertest: SuperTest<Test>;
|
||||
id: string;
|
||||
}) => {
|
||||
const { body } = await supertest
|
||||
.delete(`/api/content_management/rpc/create`)
|
||||
.set('kbn-xsrf', 'foo')
|
||||
.send({
|
||||
contentTypeId: 'index-pattern',
|
||||
id,
|
||||
options: { force: true },
|
||||
version: 1,
|
||||
});
|
||||
return body;
|
||||
};
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Client } from '@elastic/elasticsearch';
|
||||
import {
|
||||
ApmSynthtraceEsClient,
|
||||
ApmSynthtraceKibanaClient,
|
||||
createLogger,
|
||||
LogLevel,
|
||||
} from '@kbn/apm-synthtrace';
|
||||
import { apm, timerange } from '@kbn/apm-synthtrace-client';
|
||||
|
||||
export const getSyntraceClient = async ({
|
||||
kibanaUrl,
|
||||
esClient,
|
||||
}: {
|
||||
kibanaUrl: string;
|
||||
esClient: Client;
|
||||
}) => {
|
||||
const kibanaClient = new ApmSynthtraceKibanaClient({
|
||||
logger: createLogger(LogLevel.info),
|
||||
target: kibanaUrl,
|
||||
});
|
||||
const packageVersion = await kibanaClient.fetchLatestApmPackageVersion();
|
||||
return new ApmSynthtraceEsClient({
|
||||
client: esClient,
|
||||
logger: createLogger(LogLevel.info),
|
||||
refreshAfterIndex: true,
|
||||
version: packageVersion,
|
||||
});
|
||||
};
|
||||
|
||||
export const dataConfig = {
|
||||
rate: 10,
|
||||
transaction: {
|
||||
name: 'GET /data',
|
||||
duration: 1000,
|
||||
},
|
||||
service: {
|
||||
name: 'lambda-python-dev-hello',
|
||||
version: '$LATEST',
|
||||
runtime: {
|
||||
name: 'AWS_Lambda_python3.8',
|
||||
version: '3.8.11',
|
||||
},
|
||||
framework: 'AWS Lambda',
|
||||
agent: {
|
||||
name: 'python',
|
||||
version: '6.6.0',
|
||||
},
|
||||
},
|
||||
containerOs: 'linux',
|
||||
serverless: {
|
||||
firstFunctionName: 'my-function-1',
|
||||
secondFunctionName: 'my-function-2',
|
||||
faasTriggerType: 'other',
|
||||
},
|
||||
cloud: {
|
||||
provider: 'aws',
|
||||
availabilityZone: 'us-central1-c',
|
||||
region: 'us-east-1',
|
||||
machineType: 'e2-standard-4',
|
||||
projectName: 'elastic-observability',
|
||||
serviceName: 'lambda',
|
||||
},
|
||||
};
|
||||
|
||||
export async function generateData({
|
||||
synthtraceEsClient,
|
||||
start,
|
||||
end,
|
||||
}: {
|
||||
synthtraceEsClient: ApmSynthtraceEsClient;
|
||||
start: number;
|
||||
end: number;
|
||||
}) {
|
||||
const { rate, service, containerOs, serverless, cloud, transaction } = dataConfig;
|
||||
const {
|
||||
provider,
|
||||
availabilityZone,
|
||||
region,
|
||||
machineType,
|
||||
projectName,
|
||||
serviceName: cloudServiceName,
|
||||
} = cloud;
|
||||
const { faasTriggerType, firstFunctionName, secondFunctionName } = serverless;
|
||||
const { version, runtime, framework, agent, name: serviceName } = service;
|
||||
const { name: serviceRunTimeName, version: serviceRunTimeVersion } = runtime;
|
||||
const { name: agentName, version: agentVersion } = agent;
|
||||
|
||||
const instance = apm
|
||||
.service({ name: serviceName, environment: 'production', agentName })
|
||||
.instance('instance-a');
|
||||
|
||||
const traceEvents = [
|
||||
timerange(start, end)
|
||||
.interval('30s')
|
||||
.rate(rate)
|
||||
.generator((timestamp) =>
|
||||
instance
|
||||
.containerId('instance-a')
|
||||
.transaction({ transactionName: transaction.name })
|
||||
.timestamp(timestamp)
|
||||
.defaults({
|
||||
'cloud.provider': provider,
|
||||
'cloud.project.name': projectName,
|
||||
'cloud.service.name': cloudServiceName,
|
||||
'cloud.availability_zone': availabilityZone,
|
||||
'cloud.machine.type': machineType,
|
||||
'cloud.region': region,
|
||||
'faas.id': `arn:aws:lambda:us-west-2:123456789012:function:${firstFunctionName}`,
|
||||
'faas.trigger.type': faasTriggerType,
|
||||
'host.os.platform': containerOs,
|
||||
'kubernetes.pod.uid': '48f4c5a5-0625-4bea-9d94-77ee94a17e70',
|
||||
'service.version': version,
|
||||
'service.runtime.name': serviceRunTimeName,
|
||||
'service.runtime.version': serviceRunTimeVersion,
|
||||
'service.framework.name': framework,
|
||||
'agent.version': agentVersion,
|
||||
})
|
||||
.duration(transaction.duration)
|
||||
.success()
|
||||
),
|
||||
|
||||
timerange(start, end)
|
||||
.interval('30s')
|
||||
.rate(rate)
|
||||
.generator((timestamp) =>
|
||||
instance
|
||||
.transaction({ transactionName: transaction.name })
|
||||
.timestamp(timestamp)
|
||||
.defaults({
|
||||
'cloud.provider': provider,
|
||||
'cloud.project.name': projectName,
|
||||
'cloud.service.name': cloudServiceName,
|
||||
'cloud.availability_zone': availabilityZone,
|
||||
'cloud.machine.type': machineType,
|
||||
'cloud.region': region,
|
||||
'faas.id': `arn:aws:lambda:us-west-2:123456789012:function:${secondFunctionName}`,
|
||||
'faas.trigger.type': faasTriggerType,
|
||||
'host.os.platform': containerOs,
|
||||
'kubernetes.pod.uid': '48f4c5a5-0625-4bea-9d94-77ee94a17e70',
|
||||
'service.version': version,
|
||||
'service.runtime.name': serviceRunTimeName,
|
||||
'service.runtime.version': serviceRunTimeVersion,
|
||||
'service.framework.name': framework,
|
||||
'agent.version': agentVersion,
|
||||
})
|
||||
.duration(transaction.duration)
|
||||
.success()
|
||||
),
|
||||
];
|
||||
|
||||
await synthtraceEsClient.index(traceEvents);
|
||||
}
|
|
@ -9,5 +9,6 @@
|
|||
export default function ({ loadTestFile }: any) {
|
||||
describe('MetricsUI Endpoints', () => {
|
||||
loadTestFile(require.resolve('./metric_threshold_rule'));
|
||||
loadTestFile(require.resolve('./threshold_rule'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
waitForRuleStatus,
|
||||
} from './helpers/alerting_wait_for_helpers';
|
||||
import { FtrProviderContext } from '../common/ftr_provider_context';
|
||||
import { createIndexConnector, createMetricThresholdRule } from './helpers/alerting_api_helper';
|
||||
import { createIndexConnector, createRule } from './helpers/alerting_api_helper';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
|
@ -42,9 +42,11 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
name: 'Index Connector: Metric threshold API test',
|
||||
indexName: ALERT_ACTION_INDEX,
|
||||
});
|
||||
const createdRule = await createMetricThresholdRule({
|
||||
const createdRule = await createRule({
|
||||
supertest,
|
||||
ruleTypeId: InfraRuleType.MetricThreshold,
|
||||
consumer: 'infrastructure',
|
||||
tags: ['infrastructure'],
|
||||
name: 'Metric threshold rule',
|
||||
params: {
|
||||
criteria: [
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import { ApmSynthtraceEsClient } from '@kbn/apm-synthtrace';
|
||||
import { format } from 'url';
|
||||
import { Aggregators, Comparator } from '@kbn/observability-plugin/common/threshold_rule/types';
|
||||
import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/threshold/threshold_executor';
|
||||
import expect from '@kbn/expect';
|
||||
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
|
||||
import { FtrProviderContext } from '../common/ftr_provider_context';
|
||||
import { createIndexConnector, createRule } from './helpers/alerting_api_helper';
|
||||
import { createDataView, deleteDataView } from './helpers/data_view';
|
||||
import { getSyntraceClient, generateData } from './helpers/syntrace';
|
||||
import { waitForAlertInIndex, waitForRuleStatus } from './helpers/alerting_wait_for_helpers';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function ({ getService }: FtrProviderContext) {
|
||||
const start = moment(Date.now()).subtract(10, 'minutes').valueOf();
|
||||
const end = moment(Date.now()).valueOf();
|
||||
const esClient = getService('es');
|
||||
const config = getService('config');
|
||||
const kibanaServerConfig = config.get('servers.kibana');
|
||||
const kibanaUrl = format(kibanaServerConfig);
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('Threshold rule', () => {
|
||||
const THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
|
||||
const ALERT_ACTION_INDEX = 'alert-action-threshold';
|
||||
const DATA_VIEW_ID = 'data-view-id';
|
||||
|
||||
let synthtraceEsClient: ApmSynthtraceEsClient;
|
||||
let actionId: string;
|
||||
let ruleId: string;
|
||||
|
||||
before(async () => {
|
||||
synthtraceEsClient = await getSyntraceClient({ esClient, kibanaUrl });
|
||||
await generateData({ synthtraceEsClient, start, end });
|
||||
await createDataView({
|
||||
supertest,
|
||||
name: 'test-data-view',
|
||||
id: DATA_VIEW_ID,
|
||||
title: 'traces-apm*,metrics-apm*,logs-apm*',
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await supertest.delete(`/api/alerting/rule/${ruleId}`).set('kbn-xsrf', 'foo');
|
||||
await supertest.delete(`/api/actions/connector/${actionId}`).set('kbn-xsrf', 'foo');
|
||||
await esClient.deleteByQuery({
|
||||
index: THRESHOLD_RULE_ALERT_INDEX,
|
||||
query: { term: { 'kibana.alert.rule.uuid': ruleId } },
|
||||
});
|
||||
await esClient.deleteByQuery({
|
||||
index: '.kibana-event-log-*',
|
||||
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
|
||||
});
|
||||
await synthtraceEsClient.clean();
|
||||
await deleteDataView({
|
||||
supertest,
|
||||
id: DATA_VIEW_ID,
|
||||
});
|
||||
});
|
||||
|
||||
describe('Rule creation', () => {
|
||||
it('creates rule successfully', async () => {
|
||||
actionId = await createIndexConnector({
|
||||
supertest,
|
||||
name: 'Index Connector: Threshold API test',
|
||||
indexName: ALERT_ACTION_INDEX,
|
||||
});
|
||||
|
||||
const createdRule = await createRule({
|
||||
supertest,
|
||||
tags: ['observability'],
|
||||
consumer: 'alerts',
|
||||
name: 'Threshold rule',
|
||||
ruleTypeId: OBSERVABILITY_THRESHOLD_RULE_TYPE_ID,
|
||||
params: {
|
||||
criteria: [
|
||||
{
|
||||
aggType: Aggregators.CUSTOM,
|
||||
comparator: Comparator.GT,
|
||||
threshold: [7500000],
|
||||
timeSize: 5,
|
||||
timeUnit: 'm',
|
||||
customMetrics: [
|
||||
{ name: 'A', field: 'span.self_time.sum.us', aggType: Aggregators.AVERAGE },
|
||||
],
|
||||
},
|
||||
],
|
||||
alertOnNoData: true,
|
||||
alertOnGroupDisappear: true,
|
||||
searchConfiguration: {
|
||||
query: {
|
||||
query: '',
|
||||
language: 'kuery',
|
||||
},
|
||||
index: DATA_VIEW_ID,
|
||||
},
|
||||
},
|
||||
actions: [
|
||||
{
|
||||
group: FIRED_ACTIONS_ID,
|
||||
id: actionId,
|
||||
params: {
|
||||
documents: [
|
||||
{
|
||||
ruleType: '{{rule.type}}',
|
||||
},
|
||||
],
|
||||
},
|
||||
frequency: {
|
||||
notify_when: 'onActionGroupChange',
|
||||
throttle: null,
|
||||
summary: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
ruleId = createdRule.id;
|
||||
expect(ruleId).not.to.be(undefined);
|
||||
});
|
||||
|
||||
it('should be active', async () => {
|
||||
const executionStatus = await waitForRuleStatus({
|
||||
id: ruleId,
|
||||
expectedStatus: 'active',
|
||||
supertest,
|
||||
});
|
||||
expect(executionStatus.status).to.be('active');
|
||||
});
|
||||
|
||||
it('should set correct information in the alert document', async () => {
|
||||
const resp = await waitForAlertInIndex({
|
||||
esClient,
|
||||
indexName: THRESHOLD_RULE_ALERT_INDEX,
|
||||
ruleId,
|
||||
});
|
||||
|
||||
expect(resp.hits.hits[0]._source).property(
|
||||
'kibana.alert.rule.category',
|
||||
'Threshold (Technical Preview)'
|
||||
);
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.consumer', 'alerts');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.name', 'Threshold rule');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.producer', 'observability');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.revision', 0);
|
||||
expect(resp.hits.hits[0]._source).property(
|
||||
'kibana.alert.rule.rule_type_id',
|
||||
'observability.rules.threshold'
|
||||
);
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.rule.uuid', ruleId);
|
||||
expect(resp.hits.hits[0]._source).property('kibana.space_ids').contain('default');
|
||||
expect(resp.hits.hits[0]._source)
|
||||
.property('kibana.alert.rule.tags')
|
||||
.contain('observability');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.action_group', 'threshold.fired');
|
||||
expect(resp.hits.hits[0]._source).property('tags').contain('observability');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.instance.id', '*');
|
||||
expect(resp.hits.hits[0]._source).property('kibana.alert.workflow_status', 'open');
|
||||
expect(resp.hits.hits[0]._source).property('event.kind', 'signal');
|
||||
expect(resp.hits.hits[0]._source).property('event.action', 'open');
|
||||
|
||||
expect(resp.hits.hits[0]._source)
|
||||
.property('kibana.alert.rule.parameters')
|
||||
.eql({
|
||||
criteria: [
|
||||
{
|
||||
aggType: 'custom',
|
||||
comparator: '>',
|
||||
threshold: [7500000],
|
||||
timeSize: 5,
|
||||
timeUnit: 'm',
|
||||
customMetrics: [{ name: 'A', field: 'span.self_time.sum.us', aggType: 'avg' }],
|
||||
},
|
||||
],
|
||||
alertOnNoData: true,
|
||||
alertOnGroupDisappear: true,
|
||||
searchConfiguration: { index: 'data-view-id', query: { query: '', language: 'kuery' } },
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -63,6 +63,7 @@ export default function createRegisteredRuleTypeTests({ getService }: FtrProvide
|
|||
'monitoring_alert_elasticsearch_version_mismatch',
|
||||
'monitoring_ccr_read_exceptions',
|
||||
'monitoring_shard_size',
|
||||
'observability.rules.threshold',
|
||||
'apm.transaction_duration',
|
||||
'apm.anomaly',
|
||||
'apm.error_rate',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue