mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[OBS-UX-MNGMT] Move the Alerting comparators from TriggersActionsUI plugin to the alerting-types package (#181584)
## Summary
It fixes #179633
Observability created a Comparator type/enum, when ResponseOps is
already exporting one and other rules using it.
The only difference is the wording of not in between [I put the two
types side by side to compare]
Currently, we import the one in triggers-actions-ui-plugin , and then
update the not in between to match our Comparator.
### Comparing the two enums:

## For reviewers 🧪
- Everything should work as expected: Alert flyout, Alert reason
message, Rule creation flyout, etc.
- I kept the `outside` comparator (replaced by `NOT BETWEEN`) for
backward compatibility
This commit is contained in:
parent
69b28f317b
commit
4396bf6e2e
135 changed files with 1238 additions and 1079 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -21,6 +21,7 @@ x-pack/plugins/aiops @elastic/ml-ui
|
|||
x-pack/packages/ml/aiops_test_utils @elastic/ml-ui
|
||||
x-pack/test/alerting_api_integration/packages/helpers @elastic/response-ops
|
||||
x-pack/test/alerting_api_integration/common/plugins/alerts @elastic/response-ops
|
||||
x-pack/packages/kbn-alerting-comparators @elastic/response-ops
|
||||
x-pack/examples/alerting_example @elastic/response-ops
|
||||
x-pack/test/functional_with_es_ssl/plugins/alerts @elastic/response-ops
|
||||
x-pack/plugins/alerting @elastic/response-ops
|
||||
|
|
|
@ -149,6 +149,7 @@
|
|||
"@kbn/aiops-plugin": "link:x-pack/plugins/aiops",
|
||||
"@kbn/aiops-test-utils": "link:x-pack/packages/ml/aiops_test_utils",
|
||||
"@kbn/alerting-api-integration-test-plugin": "link:x-pack/test/alerting_api_integration/common/plugins/alerts",
|
||||
"@kbn/alerting-comparators": "link:x-pack/packages/kbn-alerting-comparators",
|
||||
"@kbn/alerting-example-plugin": "link:x-pack/examples/alerting_example",
|
||||
"@kbn/alerting-fixture-plugin": "link:x-pack/test/functional_with_es_ssl/plugins/alerts",
|
||||
"@kbn/alerting-plugin": "link:x-pack/plugins/alerting",
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
"@kbn/alerting-api-integration-helpers/*": ["x-pack/test/alerting_api_integration/packages/helpers/*"],
|
||||
"@kbn/alerting-api-integration-test-plugin": ["x-pack/test/alerting_api_integration/common/plugins/alerts"],
|
||||
"@kbn/alerting-api-integration-test-plugin/*": ["x-pack/test/alerting_api_integration/common/plugins/alerts/*"],
|
||||
"@kbn/alerting-comparators": ["x-pack/packages/kbn-alerting-comparators"],
|
||||
"@kbn/alerting-comparators/*": ["x-pack/packages/kbn-alerting-comparators/*"],
|
||||
"@kbn/alerting-example-plugin": ["x-pack/examples/alerting_example"],
|
||||
"@kbn/alerting-example-plugin/*": ["x-pack/examples/alerting_example/*"],
|
||||
"@kbn/alerting-fixture-plugin": ["x-pack/test/functional_with_es_ssl/plugins/alerts"],
|
||||
|
|
5
x-pack/packages/kbn-alerting-comparators/README.md
Normal file
5
x-pack/packages/kbn-alerting-comparators/README.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
# @kbn/alerting-comparators
|
||||
|
||||
Contains type information and enum for the alerting rule comparators. e.g. >, <
|
||||
|
||||
This comparators are used extensively in Observability UI and server side. Also, in the triggers-actions-ui in some related UI like ThresholdExpression.
|
7
x-pack/packages/kbn-alerting-comparators/index.ts
Normal file
7
x-pack/packages/kbn-alerting-comparators/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
export * from './src/comparators';
|
12
x-pack/packages/kbn-alerting-comparators/jest.config.js
Normal file
12
x-pack/packages/kbn-alerting-comparators/jest.config.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test/jest_node',
|
||||
rootDir: '../../..',
|
||||
roots: ['<rootDir>/x-pack/packages/kbn-alerting-comparators'],
|
||||
};
|
5
x-pack/packages/kbn-alerting-comparators/kibana.jsonc
Normal file
5
x-pack/packages/kbn-alerting-comparators/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/alerting-comparators",
|
||||
"owner": "@elastic/response-ops"
|
||||
}
|
6
x-pack/packages/kbn-alerting-comparators/package.json
Normal file
6
x-pack/packages/kbn-alerting-comparators/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "@kbn/alerting-comparators",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"license": "Elastic License 2.0"
|
||||
}
|
20
x-pack/packages/kbn-alerting-comparators/src/comparators.ts
Normal file
20
x-pack/packages/kbn-alerting-comparators/src/comparators.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export interface Comparator {
|
||||
text: string;
|
||||
value: string;
|
||||
requiredValues: number;
|
||||
}
|
||||
export enum COMPARATORS {
|
||||
GREATER_THAN = '>',
|
||||
GREATER_THAN_OR_EQUALS = '>=',
|
||||
BETWEEN = 'between',
|
||||
LESS_THAN = '<',
|
||||
LESS_THAN_OR_EQUALS = '<=',
|
||||
NOT_BETWEEN = 'notBetween',
|
||||
}
|
18
x-pack/packages/kbn-alerting-comparators/tsconfig.json
Normal file
18
x-pack/packages/kbn-alerting-comparators/tsconfig.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
]
|
||||
}
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
|
||||
import { FIRED_ACTIONS_ID } from './constants';
|
||||
import { createRule } from './create_rule';
|
||||
|
@ -38,7 +36,7 @@ export const createCustomThresholdRule = async (
|
|||
params: {
|
||||
criteria: ruleParams.params?.criteria || [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [1],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
|
||||
export const scenario1 = {
|
||||
dataView: {
|
||||
|
@ -22,7 +20,7 @@ export const scenario1 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [100],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export const scenario2 = {
|
||||
dataView: {
|
||||
|
@ -22,7 +20,7 @@ export const scenario2 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [40],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,11 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
export const scenario3 = {
|
||||
dataView: {
|
||||
indexPattern: 'high-cardinality-data-fake_hosts.fake_hosts-*',
|
||||
|
@ -22,7 +19,7 @@ export const scenario3 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [5],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export const scenario4 = {
|
||||
dataView: {
|
||||
|
@ -22,7 +20,7 @@ export const scenario4 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [80],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export const scenario5 = {
|
||||
dataView: {
|
||||
|
@ -22,7 +20,7 @@ export const scenario5 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [80],
|
||||
timeSize: 5,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
} from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '@kbn/observability-plugin/common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export const scenario6 = {
|
||||
dataView: {
|
||||
|
@ -22,7 +20,7 @@ export const scenario6 = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -18,5 +18,6 @@
|
|||
"kbn_references": [
|
||||
"@kbn/observability-plugin",
|
||||
"@kbn/rule-data-utils",
|
||||
"@kbn/alerting-comparators",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
"@kbn/data-views-plugin",
|
||||
"@kbn/share-plugin",
|
||||
"@kbn/safer-lodash-set",
|
||||
"@kbn/alerting-state-types",
|
||||
"@kbn/alerting-types",
|
||||
"@kbn/alerts-as-data-utils",
|
||||
"@kbn/core-elasticsearch-client-server-mocks",
|
||||
|
@ -70,7 +69,8 @@
|
|||
"@kbn/core-execution-context-server-mocks",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/search-types",
|
||||
"@kbn/core-security-server",
|
||||
"@kbn/alerting-state-types",
|
||||
"@kbn/core-security-server"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import * as rt from 'io-ts';
|
||||
import { TimeUnitChar } from '@kbn/observability-plugin/common/utils/formatters/duration';
|
||||
import { ML_ANOMALY_THRESHOLD } from '@kbn/ml-anomaly-utils/anomaly_threshold';
|
||||
import { InventoryItemType, SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { LEGACY_COMPARATORS } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator';
|
||||
import { SnapshotCustomMetricInput } from '../../http_api';
|
||||
|
||||
export const METRIC_THRESHOLD_ALERT_TYPE_ID = 'metrics.alert.threshold';
|
||||
|
@ -18,20 +18,6 @@ export enum InfraRuleType {
|
|||
InventoryThreshold = 'metrics.alert.inventory.threshold',
|
||||
}
|
||||
|
||||
export interface InfraRuleTypeParams {
|
||||
[InfraRuleType.MetricThreshold]: MetricThresholdParams;
|
||||
[InfraRuleType.InventoryThreshold]: InventoryMetricConditions;
|
||||
}
|
||||
|
||||
export enum Comparator {
|
||||
GT = '>',
|
||||
LT = '<',
|
||||
GT_OR_EQ = '>=',
|
||||
LT_OR_EQ = '<=',
|
||||
BETWEEN = 'between',
|
||||
OUTSIDE_RANGE = 'outside',
|
||||
}
|
||||
|
||||
export enum Aggregators {
|
||||
COUNT = 'count',
|
||||
AVERAGE = 'avg',
|
||||
|
@ -53,27 +39,6 @@ export enum AlertStates {
|
|||
ERROR,
|
||||
}
|
||||
|
||||
const metricAnomalyNodeTypeRT = rt.union([rt.literal('hosts'), rt.literal('k8s')]);
|
||||
const metricAnomalyMetricRT = rt.union([
|
||||
rt.literal('memory_usage'),
|
||||
rt.literal('network_in'),
|
||||
rt.literal('network_out'),
|
||||
]);
|
||||
const metricAnomalyInfluencerFilterRT = rt.type({
|
||||
fieldName: rt.string,
|
||||
fieldValue: rt.string,
|
||||
});
|
||||
|
||||
export interface MetricAnomalyParams {
|
||||
nodeType: rt.TypeOf<typeof metricAnomalyNodeTypeRT>;
|
||||
metric: rt.TypeOf<typeof metricAnomalyMetricRT>;
|
||||
alertInterval?: string;
|
||||
sourceId?: string;
|
||||
spaceId?: string;
|
||||
threshold: Exclude<ML_ANOMALY_THRESHOLD, ML_ANOMALY_THRESHOLD.LOW>;
|
||||
influencerFilter: rt.TypeOf<typeof metricAnomalyInfluencerFilterRT> | undefined;
|
||||
}
|
||||
|
||||
// Types for the executor
|
||||
|
||||
export interface InventoryMetricConditions {
|
||||
|
@ -82,10 +47,10 @@ export interface InventoryMetricConditions {
|
|||
timeUnit: TimeUnitChar;
|
||||
sourceId?: string;
|
||||
threshold: number[];
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS | LEGACY_COMPARATORS;
|
||||
customMetric?: SnapshotCustomMetricInput;
|
||||
warningThreshold?: number[];
|
||||
warningComparator?: Comparator;
|
||||
warningComparator?: COMPARATORS | LEGACY_COMPARATORS;
|
||||
}
|
||||
|
||||
export interface InventoryMetricThresholdParams {
|
||||
|
@ -111,8 +76,8 @@ interface BaseMetricExpressionParams {
|
|||
timeUnit: TimeUnitChar;
|
||||
sourceId?: string;
|
||||
threshold: number[];
|
||||
comparator: Comparator;
|
||||
warningComparator?: Comparator;
|
||||
comparator: COMPARATORS | LEGACY_COMPARATORS;
|
||||
warningComparator?: COMPARATORS | LEGACY_COMPARATORS;
|
||||
warningThreshold?: number[];
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { LIGHT_THEME } from '@elastic/charts';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Props, Threshold as Component } from './threshold';
|
||||
|
||||
export default {
|
||||
|
@ -30,7 +30,7 @@ export default {
|
|||
|
||||
const defaultProps: Props = {
|
||||
chartProps: { baseTheme: LIGHT_THEME },
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
id: 'componentId',
|
||||
threshold: 90,
|
||||
title: 'Threshold breached',
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { LIGHT_THEME } from '@elastic/charts';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { render } from '@testing-library/react';
|
||||
import { Props, Threshold } from './threshold';
|
||||
import React from 'react';
|
||||
|
@ -15,7 +15,7 @@ describe('Threshold', () => {
|
|||
const renderComponent = (props: Partial<Props> = {}) => {
|
||||
const defaultProps: Props = {
|
||||
chartProps: { baseTheme: LIGHT_THEME },
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
id: 'componentId',
|
||||
threshold: 90,
|
||||
title: 'Threshold breached',
|
||||
|
|
|
@ -10,8 +10,7 @@ import { Chart, Metric, Settings } from '@elastic/charts';
|
|||
import { EuiIcon, EuiPanel, useEuiBackgroundColor } from '@elastic/eui';
|
||||
import type { PartialTheme, Theme } from '@elastic/charts';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
export interface ChartProps {
|
||||
theme?: PartialTheme;
|
||||
baseTheme: Theme;
|
||||
|
@ -19,7 +18,7 @@ export interface ChartProps {
|
|||
|
||||
export interface Props {
|
||||
chartProps: ChartProps;
|
||||
comparator: Comparator | string;
|
||||
comparator: COMPARATORS | string;
|
||||
id: string;
|
||||
threshold: number;
|
||||
title: string;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Color } from '../../../../common/color_palette';
|
||||
import { ThresholdAnnotations } from './threshold_annotations';
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('ThresholdAnnotations', () => {
|
|||
const defaultProps = {
|
||||
threshold: [20, 30],
|
||||
sortedThresholds: [20, 30],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
color: Color.color0,
|
||||
id: 'testId',
|
||||
firstTimestamp: 123456789,
|
||||
|
@ -53,7 +53,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for in between thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.BETWEEN });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="between-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -72,7 +72,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render an upper rectangular annotation for outside range thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.OUTSIDE_RANGE });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.NOT_BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="outside-range-lower-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -91,7 +91,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a lower rectangular annotation for outside range thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.OUTSIDE_RANGE });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.NOT_BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="outside-range-upper-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -110,7 +110,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for below thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.LT });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.LESS_THAN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="below-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -129,7 +129,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for above thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.GT });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.GREATER_THAN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="above-rect"]');
|
||||
const expectedValues = [
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
import { AnnotationDomainType, LineAnnotation, RectAnnotation } from '@elastic/charts';
|
||||
import { first, last } from 'lodash';
|
||||
import React from 'react';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Color, colorTransformer } from '../../../../common/color_palette';
|
||||
|
||||
interface ThresholdAnnotationsProps {
|
||||
threshold: number[];
|
||||
sortedThresholds: number[];
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
color: Color;
|
||||
id: string;
|
||||
firstTimestamp: number;
|
||||
|
@ -34,8 +34,10 @@ export const ThresholdAnnotations = ({
|
|||
domain,
|
||||
}: ThresholdAnnotationsProps) => {
|
||||
if (!comparator || !threshold) return null;
|
||||
const isAbove = [Comparator.GT, Comparator.GT_OR_EQ].includes(comparator);
|
||||
const isBelow = [Comparator.LT, Comparator.LT_OR_EQ].includes(comparator);
|
||||
const isAbove = [COMPARATORS.GREATER_THAN, COMPARATORS.GREATER_THAN_OR_EQUALS].includes(
|
||||
comparator
|
||||
);
|
||||
const isBelow = [COMPARATORS.LESS_THAN, COMPARATORS.LESS_THAN_OR_EQUALS].includes(comparator);
|
||||
return (
|
||||
<>
|
||||
<LineAnnotation
|
||||
|
@ -53,7 +55,7 @@ export const ThresholdAnnotations = ({
|
|||
},
|
||||
}}
|
||||
/>
|
||||
{sortedThresholds.length === 2 && comparator === Comparator.BETWEEN ? (
|
||||
{sortedThresholds.length === 2 && comparator === COMPARATORS.BETWEEN ? (
|
||||
<>
|
||||
<RectAnnotation
|
||||
id={`${id}-lower-threshold`}
|
||||
|
@ -75,7 +77,7 @@ export const ThresholdAnnotations = ({
|
|||
/>
|
||||
</>
|
||||
) : null}
|
||||
{sortedThresholds.length === 2 && comparator === Comparator.OUTSIDE_RANGE ? (
|
||||
{sortedThresholds.length === 2 && comparator === COMPARATORS.NOT_BETWEEN ? (
|
||||
<>
|
||||
<RectAnnotation
|
||||
id={`${id}-lower-threshold`}
|
||||
|
|
|
@ -11,7 +11,8 @@ import { act } from 'react-dom/test-utils';
|
|||
import { DataView, type FieldSpec } from '@kbn/data-views-plugin/common';
|
||||
// We are using this inside a `jest.mock` call. Jest requires dynamic dependencies to be prefixed with `mock`
|
||||
import { coreMock as mockCoreMock } from '@kbn/core/public/mocks';
|
||||
import { Comparator, InventoryMetricConditions } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { InventoryMetricConditions } from '../../../../common/alerting/metrics';
|
||||
import { AlertContextMeta, defaultExpression, ExpressionRow, Expressions } from './expression';
|
||||
import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks';
|
||||
import { ResolvedDataView } from '../../../utils/data_view';
|
||||
|
@ -111,7 +112,7 @@ describe('Expression', () => {
|
|||
expect(ruleParams.criteria).toEqual([
|
||||
{
|
||||
metric: 'memory',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -131,7 +132,7 @@ describe('Expression', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [10],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
],
|
||||
nodeType: undefined,
|
||||
|
@ -173,7 +174,7 @@ describe('Expression', () => {
|
|||
expect(ruleParams.criteria).toEqual([
|
||||
{
|
||||
metric: 'custom',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -217,7 +218,7 @@ describe('ExpressionRow', () => {
|
|||
}
|
||||
const expression = {
|
||||
metric: 'custom',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -52,16 +52,17 @@ import {
|
|||
SnapshotMetricType,
|
||||
SnapshotMetricTypeRT,
|
||||
} from '@kbn/metrics-data-access-plugin/common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import {
|
||||
SnapshotCustomMetricInput,
|
||||
SnapshotCustomMetricInputRT,
|
||||
} from '../../../../common/http_api';
|
||||
import {
|
||||
Comparator,
|
||||
FilterQuery,
|
||||
InventoryMetricConditions,
|
||||
QUERY_INVALID,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import {
|
||||
SnapshotCustomMetricInput,
|
||||
SnapshotCustomMetricInputRT,
|
||||
} from '../../../../common/http_api/snapshot_api';
|
||||
import { toMetricOpt } from '../../../../common/snapshot_metric_i18n';
|
||||
import {
|
||||
useMetricsDataViewContext,
|
||||
|
@ -106,7 +107,7 @@ type Props = Omit<
|
|||
|
||||
export const defaultExpression = {
|
||||
metric: 'cpu' as SnapshotMetricType,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -447,7 +448,7 @@ export const ExpressionRow: FC<PropsWithChildren<ExpressionRowProps>> = (props)
|
|||
const { children, setRuleParams, expression, errors, expressionId, remove, canDelete } = props;
|
||||
const {
|
||||
metric,
|
||||
comparator = Comparator.GT,
|
||||
comparator = COMPARATORS.GREATER_THAN,
|
||||
threshold = [],
|
||||
customMetric,
|
||||
warningThreshold = [],
|
||||
|
@ -478,14 +479,14 @@ export const ExpressionRow: FC<PropsWithChildren<ExpressionRowProps>> = (props)
|
|||
|
||||
const updateComparator = useCallback(
|
||||
(c?: string) => {
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as Comparator | undefined });
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as COMPARATORS | undefined });
|
||||
},
|
||||
[expressionId, expression, setRuleParams]
|
||||
);
|
||||
|
||||
const updateWarningComparator = useCallback(
|
||||
(c?: string) => {
|
||||
setRuleParams(expressionId, { ...expression, warningComparator: c as Comparator });
|
||||
setRuleParams(expressionId, { ...expression, warningComparator: c as COMPARATORS });
|
||||
},
|
||||
[expressionId, expression, setRuleParams]
|
||||
);
|
||||
|
@ -713,7 +714,7 @@ const ThresholdElement: React.FC<{
|
|||
<>
|
||||
<div css={StyledExpressionCss}>
|
||||
<ThresholdExpression
|
||||
thresholdComparator={comparator || Comparator.GT}
|
||||
thresholdComparator={convertToBuiltInComparators(comparator) || COMPARATORS.GREATER_THAN}
|
||||
threshold={threshold}
|
||||
onChangeSelectedThresholdComparator={updateComparator}
|
||||
onChangeSelectedThreshold={updateThreshold}
|
||||
|
|
|
@ -12,6 +12,7 @@ import moment from 'moment';
|
|||
import React, { useCallback, useMemo } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { InventoryItemType, SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { useTimelineChartTheme } from '../../../utils/use_timeline_chart_theme';
|
||||
import { InventoryMetricConditions } from '../../../../common/alerting/metrics';
|
||||
import { Color } from '../../../../common/color_palette';
|
||||
|
@ -166,7 +167,7 @@ export const ExpressionChart: React.FC<Props> = ({
|
|||
stack={false}
|
||||
/>
|
||||
<ThresholdAnnotations
|
||||
comparator={expression.comparator}
|
||||
comparator={convertToBuiltInComparators(expression.comparator)}
|
||||
threshold={convertedThresholds}
|
||||
sortedThresholds={criticalThresholds}
|
||||
color={Color.color1}
|
||||
|
@ -177,7 +178,7 @@ export const ExpressionChart: React.FC<Props> = ({
|
|||
/>
|
||||
{expression.warningComparator && expression.warningThreshold && (
|
||||
<ThresholdAnnotations
|
||||
comparator={expression.warningComparator}
|
||||
comparator={convertToBuiltInComparators(expression.warningComparator)}
|
||||
threshold={convertedWarningThresholds}
|
||||
sortedThresholds={warningThresholds}
|
||||
color={Color.color5}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { ValidationResult } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Comparator,
|
||||
FilterQuery,
|
||||
InventoryMetricConditions,
|
||||
QUERY_INVALID,
|
||||
|
@ -91,7 +91,7 @@ export function validateMetricThreshold({
|
|||
// The Threshold component returns an empty array with a length ([empty]) because it's using delete newThreshold[i].
|
||||
// We need to use [...c.threshold] to convert it to an array with an undefined value ([undefined]) so we can test each element.
|
||||
const { comparator, threshold, type } = props as {
|
||||
comparator?: Comparator;
|
||||
comparator?: COMPARATORS;
|
||||
threshold?: number[];
|
||||
type: 'critical' | 'warning';
|
||||
};
|
||||
|
@ -108,7 +108,7 @@ export function validateMetricThreshold({
|
|||
});
|
||||
}
|
||||
|
||||
if (comparator === Comparator.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
if (comparator === COMPARATORS.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
errors[id][type].threshold1.push(
|
||||
i18n.translate('xpack.infra.metrics.alertFlyout.error.thresholdRequired', {
|
||||
defaultMessage: 'Threshold is required.',
|
||||
|
|
|
@ -9,11 +9,8 @@ import { Meta, Story } from '@storybook/react/types-6-0';
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { TimeUnitChar } from '@kbn/observability-plugin/common';
|
||||
import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
MetricExpressionParams,
|
||||
} from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators, MetricExpressionParams } from '../../../../../common/alerting/metrics';
|
||||
import { decorateWithGlobalStorybookThemeProviders } from '../../../../test_utils/use_global_storybook_theme';
|
||||
import { CustomEquationEditor, CustomEquationEditorProps } from './custom_equation_editor';
|
||||
import { aggregationType } from '../expression_row';
|
||||
|
@ -74,7 +71,7 @@ const BASE_ARGS = {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm' as TimeUnitChar,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
fields: [
|
||||
{ name: 'system.cpu.user.pct', normalizedType: 'number' },
|
||||
|
|
|
@ -10,7 +10,7 @@ import React from 'react';
|
|||
import { act } from 'react-dom/test-utils';
|
||||
// We are using this inside a `jest.mock` call. Jest requires dynamic dependencies to be prefixed with `mock`
|
||||
import { coreMock as mockCoreMock } from '@kbn/core/public/mocks';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { MetricsExplorerMetric } from '../../../../common/http_api/metrics_explorer';
|
||||
import { Expressions } from './expression';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
|
@ -102,7 +102,7 @@ describe('Expression', () => {
|
|||
expect(ruleParams.criteria).toEqual([
|
||||
{
|
||||
metric: 'system.load.1',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -110,7 +110,7 @@ describe('Expression', () => {
|
|||
},
|
||||
{
|
||||
metric: 'system.cpu.user.pct',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -28,12 +28,13 @@ import {
|
|||
RuleTypeParamsExpressionProps,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { TimeUnitChar } from '@kbn/observability-plugin/common/utils/formatters/duration';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators, QUERY_INVALID } from '../../../../common/alerting/metrics';
|
||||
import {
|
||||
useMetricsDataViewContext,
|
||||
useSourceContext,
|
||||
withSourceProvider,
|
||||
} from '../../../containers/metrics_source';
|
||||
import { Aggregators, Comparator, QUERY_INVALID } from '../../../../common/alerting/metrics';
|
||||
import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
|
||||
import { MetricsExplorerGroupBy } from '../../../pages/metrics/metrics_explorer/components/group_by';
|
||||
import { MetricsExplorerKueryBar } from '../../../pages/metrics/metrics_explorer/components/kuery_bar';
|
||||
|
@ -57,7 +58,7 @@ type Props = Omit<
|
|||
|
||||
const defaultExpression = {
|
||||
aggType: Aggregators.AVERAGE,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -182,7 +183,7 @@ export const Expressions: React.FC<Props> = (props) => {
|
|||
'criteria',
|
||||
md.currentOptions.metrics.map((metric) => ({
|
||||
metric: metric.field,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [],
|
||||
timeSize,
|
||||
timeUnit,
|
||||
|
|
|
@ -11,7 +11,8 @@ import { LineAnnotation, RectAnnotation } from '@elastic/charts';
|
|||
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
||||
// We are using this inside a `jest.mock` call. Jest requires dynamic dependencies to be prefixed with `mock`
|
||||
import { coreMock as mockCoreMock } from '@kbn/core/public/mocks';
|
||||
import { Aggregators, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { Aggregators } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { MetricExpression } from '../types';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { ExpressionChart } from './expression_chart';
|
||||
|
@ -105,7 +106,7 @@ describe('ExpressionChart', () => {
|
|||
timeUnit: 'm',
|
||||
sourceId: 'default',
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
};
|
||||
const { wrapper } = await setup(expression);
|
||||
expect(wrapper.find('[data-test-subj~="noChartData"]').exists()).toBeTruthy();
|
||||
|
|
|
@ -22,6 +22,7 @@ import { useActiveCursor } from '@kbn/charts-plugin/public';
|
|||
import { first, last } from 'lodash';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { useTimelineChartTheme } from '../../../utils/use_timeline_chart_theme';
|
||||
import { Color } from '../../../../common/color_palette';
|
||||
import { MetricsExplorerRow, MetricsExplorerAggregation } from '../../../../common/http_api';
|
||||
|
@ -155,7 +156,7 @@ export const ExpressionChart: React.FC<Props> = ({
|
|||
stack={false}
|
||||
/>
|
||||
<ThresholdAnnotations
|
||||
comparator={expression.comparator}
|
||||
comparator={convertToBuiltInComparators(expression.comparator)}
|
||||
threshold={expression.threshold}
|
||||
sortedThresholds={criticalThresholds}
|
||||
color={Color.color1}
|
||||
|
@ -166,7 +167,7 @@ export const ExpressionChart: React.FC<Props> = ({
|
|||
/>
|
||||
{expression.warningComparator && expression.warningThreshold && (
|
||||
<ThresholdAnnotations
|
||||
comparator={expression.warningComparator}
|
||||
comparator={convertToBuiltInComparators(expression.comparator)}
|
||||
threshold={expression.warningThreshold}
|
||||
sortedThresholds={warningThresholds}
|
||||
color={Color.color5}
|
||||
|
|
|
@ -9,7 +9,7 @@ import { ResolvedDataView } from '../../../utils/data_view';
|
|||
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { MetricExpression } from '../types';
|
||||
import { ExpressionRow } from './expression_row';
|
||||
import { TIMESTAMP_FIELD } from '../../../../common/constants';
|
||||
|
@ -88,7 +88,7 @@ describe('ExpressionRow', () => {
|
|||
it('should display thresholds as a percentage for pct metrics', async () => {
|
||||
const expression = {
|
||||
metric: 'system.cpu.user.pct',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.5],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -107,7 +107,7 @@ describe('ExpressionRow', () => {
|
|||
it('should display thresholds as a decimal for all other metrics', async () => {
|
||||
const expression = {
|
||||
metric: 'system.load.1',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.5],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -125,7 +125,7 @@ describe('ExpressionRow', () => {
|
|||
it('should render a helpText for the of expression', async () => {
|
||||
const expression = {
|
||||
metric: 'system.load.1',
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.5],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -21,31 +21,21 @@ import React, { PropsWithChildren, useCallback, useMemo, useState } from 'react'
|
|||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
import {
|
||||
AggregationType,
|
||||
builtInComparators,
|
||||
IErrorObject,
|
||||
OfExpression,
|
||||
ThresholdExpression,
|
||||
WhenExpression,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import useToggle from 'react-use/lib/useToggle';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { Aggregators } from '../../../../common/alerting/metrics';
|
||||
import { useMetricsDataViewContext } from '../../../containers/metrics_source';
|
||||
import { Aggregators, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { decimalToPct, pctToDecimal } from '../../../../common/utils/corrected_percent_convert';
|
||||
import { AGGREGATION_TYPES, MetricExpression } from '../types';
|
||||
import { CustomEquationEditor } from './custom_equation';
|
||||
import { CUSTOM_EQUATION } from '../i18n_strings';
|
||||
|
||||
const customComparators = {
|
||||
...builtInComparators,
|
||||
[Comparator.OUTSIDE_RANGE]: {
|
||||
text: i18n.translate('xpack.infra.metrics.alertFlyout.outsideRangeLabel', {
|
||||
defaultMessage: 'Is not between',
|
||||
}),
|
||||
value: Comparator.OUTSIDE_RANGE,
|
||||
requiredValues: 2,
|
||||
},
|
||||
};
|
||||
|
||||
interface ExpressionRowProps {
|
||||
expressionId: number;
|
||||
expression: MetricExpression;
|
||||
|
@ -81,7 +71,7 @@ export const ExpressionRow = ({
|
|||
const {
|
||||
aggType = AGGREGATION_TYPES.MAX,
|
||||
metric,
|
||||
comparator = Comparator.GT,
|
||||
comparator = COMPARATORS.GREATER_THAN,
|
||||
threshold = [],
|
||||
warningThreshold = [],
|
||||
warningComparator,
|
||||
|
@ -115,14 +105,14 @@ export const ExpressionRow = ({
|
|||
|
||||
const updateComparator = useCallback(
|
||||
(c?: string) => {
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as Comparator });
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as COMPARATORS });
|
||||
},
|
||||
[expressionId, expression, setRuleParams]
|
||||
);
|
||||
|
||||
const updateWarningComparator = useCallback(
|
||||
(c?: string) => {
|
||||
setRuleParams(expressionId, { ...expression, warningComparator: c as Comparator });
|
||||
setRuleParams(expressionId, { ...expression, warningComparator: c as COMPARATORS });
|
||||
},
|
||||
[expressionId, expression, setRuleParams]
|
||||
);
|
||||
|
@ -373,14 +363,18 @@ const ThresholdElement: React.FC<{
|
|||
if (isMetricPct) return threshold.map((v) => decimalToPct(v));
|
||||
return threshold;
|
||||
}, [threshold, isMetricPct]);
|
||||
|
||||
const thresholdComparator = useCallback(() => {
|
||||
if (!comparator) return COMPARATORS.GREATER_THAN;
|
||||
// Check if the rule had the legacy OUTSIDE_RANGE inside its params.
|
||||
// Then, change it on-the-fly to NOT_BETWEEN
|
||||
return convertToBuiltInComparators(comparator);
|
||||
}, [comparator]);
|
||||
return (
|
||||
<>
|
||||
<StyledExpression>
|
||||
<ThresholdExpression
|
||||
thresholdComparator={comparator || Comparator.GT}
|
||||
thresholdComparator={thresholdComparator()}
|
||||
threshold={displayedThreshold}
|
||||
customComparators={customComparators}
|
||||
onChangeSelectedThresholdComparator={updateComparator}
|
||||
onChangeSelectedThreshold={updateThreshold}
|
||||
errors={errors}
|
||||
|
|
|
@ -9,15 +9,14 @@ import { fromKueryExpression } from '@kbn/es-query';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { ValidationResult } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
FilterQuery,
|
||||
MetricExpressionParams,
|
||||
QUERY_INVALID,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
|
||||
export const EQUATION_REGEX = /[^A-Z|+|\-|\s|\d+|\.|\(|\)|\/|\*|>|<|=|\?|\:|&|\!|\|]+/g;
|
||||
|
||||
const isCustomMetricExpressionParams = (
|
||||
|
@ -118,7 +117,7 @@ export function validateMetricThreshold({
|
|||
// The Threshold component returns an empty array with a length ([empty]) because it's using delete newThreshold[i].
|
||||
// We need to use [...c.threshold] to convert it to an array with an undefined value ([undefined]) so we can test each element.
|
||||
const { comparator, threshold, type } = props as {
|
||||
comparator?: Comparator;
|
||||
comparator?: COMPARATORS;
|
||||
threshold?: number[];
|
||||
type: 'critical' | 'warning';
|
||||
};
|
||||
|
@ -135,7 +134,7 @@ export function validateMetricThreshold({
|
|||
});
|
||||
}
|
||||
|
||||
if (comparator === Comparator.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
if (comparator === COMPARATORS.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
errors[id][type].threshold1.push(
|
||||
i18n.translate('xpack.infra.metrics.alertFlyout.error.thresholdRequired', {
|
||||
defaultMessage: 'Threshold is required.',
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Aggregators, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators } from '../../../../common/alerting/metrics';
|
||||
import { MetricExpression } from '../types';
|
||||
import { generateUniqueKey } from './generate_unique_key';
|
||||
|
||||
|
@ -14,7 +14,7 @@ describe('generateUniqueKey', () => {
|
|||
[
|
||||
{
|
||||
aggType: Aggregators.COUNT,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [2000, 5000],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
|
@ -24,7 +24,7 @@ describe('generateUniqueKey', () => {
|
|||
[
|
||||
{
|
||||
aggType: Aggregators.CUSTOM,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [30],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
|
@ -34,7 +34,7 @@ describe('generateUniqueKey', () => {
|
|||
[
|
||||
{
|
||||
aggType: Aggregators.AVERAGE,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [500],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { Aggregators, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators } from '../../../../common/alerting/metrics';
|
||||
import { MetricThresholdAlert, MetricThresholdRule } from '../components/alert_details_app_section';
|
||||
|
||||
export const buildMetricThresholdRule = (
|
||||
|
@ -59,24 +60,24 @@ export const buildMetricThresholdRule = (
|
|||
criteria: [
|
||||
{
|
||||
aggType: Aggregators.COUNT,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [2000],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
},
|
||||
{
|
||||
aggType: Aggregators.MAX,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [4],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
metric: 'system.cpu.user.pct',
|
||||
warningComparator: Comparator.GT,
|
||||
warningComparator: COMPARATORS.GREATER_THAN,
|
||||
warningThreshold: [2.2],
|
||||
},
|
||||
{
|
||||
aggType: Aggregators.MIN,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.8],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
|
@ -131,7 +132,7 @@ export const buildMetricThresholdAlert = (
|
|||
criteria: [
|
||||
{
|
||||
aggType: Aggregators.AVERAGE,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [2000],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
|
@ -139,12 +140,12 @@ export const buildMetricThresholdAlert = (
|
|||
},
|
||||
{
|
||||
aggType: Aggregators.MAX,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [4],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
metric: 'system.cpu.user.pct',
|
||||
warningComparator: Comparator.GT,
|
||||
warningComparator: COMPARATORS.GREATER_THAN,
|
||||
warningThreshold: [2.2],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -10,7 +10,8 @@ import {
|
|||
formatDurationFromTimeUnitChar,
|
||||
TimeUnitChar,
|
||||
} from '@kbn/observability-plugin/common/utils/formatters/duration';
|
||||
import { AlertStates, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { AlertStates } from '../../../../common/alerting/metrics';
|
||||
import { UNGROUPED_FACTORY_KEY } from './utils';
|
||||
|
||||
export const DOCUMENT_COUNT_I18N = i18n.translate(
|
||||
|
@ -49,7 +50,7 @@ const toNumber = (value: number | string) =>
|
|||
typeof value === 'string' ? parseFloat(value) : value;
|
||||
|
||||
const recoveredComparatorToI18n = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
currentValue: number
|
||||
) => {
|
||||
|
@ -60,20 +61,49 @@ const recoveredComparatorToI18n = (
|
|||
defaultMessage: 'above',
|
||||
});
|
||||
switch (comparator) {
|
||||
case Comparator.BETWEEN:
|
||||
case COMPARATORS.BETWEEN:
|
||||
return currentValue < threshold[0] ? belowText : aboveText;
|
||||
case Comparator.OUTSIDE_RANGE:
|
||||
case COMPARATORS.NOT_BETWEEN:
|
||||
return i18n.translate('xpack.infra.metrics.alerting.threshold.betweenRecovery', {
|
||||
defaultMessage: 'between',
|
||||
});
|
||||
case Comparator.GT:
|
||||
case Comparator.GT_OR_EQ:
|
||||
case COMPARATORS.GREATER_THAN:
|
||||
case COMPARATORS.GREATER_THAN_OR_EQUALS:
|
||||
return belowText;
|
||||
case Comparator.LT:
|
||||
case Comparator.LT_OR_EQ:
|
||||
case COMPARATORS.LESS_THAN:
|
||||
case COMPARATORS.LESS_THAN_OR_EQUALS:
|
||||
return aboveText;
|
||||
}
|
||||
};
|
||||
const alertComparatorToI18n = (comparator: COMPARATORS) => {
|
||||
switch (comparator) {
|
||||
case COMPARATORS.BETWEEN:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.between', {
|
||||
defaultMessage: 'between',
|
||||
});
|
||||
case COMPARATORS.NOT_BETWEEN:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.notBetween', {
|
||||
defaultMessage: 'not between',
|
||||
});
|
||||
case COMPARATORS.GREATER_THAN:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.above', {
|
||||
defaultMessage: 'above',
|
||||
});
|
||||
case COMPARATORS.GREATER_THAN_OR_EQUALS:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.aboveOrEqual', {
|
||||
defaultMessage: 'above or equal',
|
||||
});
|
||||
case COMPARATORS.LESS_THAN:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.below', {
|
||||
defaultMessage: 'below',
|
||||
});
|
||||
|
||||
case COMPARATORS.LESS_THAN_OR_EQUALS:
|
||||
return i18n.translate('xpack.infra.customThreshold.rule.threshold.belowOrEqual', {
|
||||
defaultMessage: 'below or equal',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const thresholdToI18n = ([a, b]: Array<number | string>) => {
|
||||
if (typeof b === 'undefined') return a;
|
||||
|
@ -88,7 +118,7 @@ const formatGroup = (group: string) => (group === UNGROUPED_FACTORY_KEY ? '' : `
|
|||
export const buildFiredAlertReason: (alertResult: {
|
||||
group: string;
|
||||
metric: string;
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
threshold: Array<number | string>;
|
||||
currentValue: number | string;
|
||||
timeSize: number;
|
||||
|
@ -100,7 +130,7 @@ export const buildFiredAlertReason: (alertResult: {
|
|||
values: {
|
||||
group: formatGroup(group),
|
||||
metric,
|
||||
comparator,
|
||||
comparator: alertComparatorToI18n(comparator),
|
||||
threshold: thresholdToI18n(threshold),
|
||||
currentValue,
|
||||
duration: formatDurationFromTimeUnitChar(timeSize, timeUnit),
|
||||
|
@ -111,7 +141,7 @@ export const buildFiredAlertReason: (alertResult: {
|
|||
export const buildRecoveredAlertReason: (alertResult: {
|
||||
group: string;
|
||||
metric: string;
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
threshold: Array<number | string>;
|
||||
currentValue: number | string;
|
||||
}) => string = ({ group, metric, comparator, threshold, currentValue }) =>
|
||||
|
|
|
@ -13,12 +13,8 @@ import { RuleExecutorServicesMock, alertsMock } from '@kbn/alerting-plugin/serve
|
|||
import { LifecycleAlertServices } from '@kbn/rule-registry-plugin/server';
|
||||
import { ruleRegistryMocks } from '@kbn/rule-registry-plugin/server/mocks';
|
||||
import { createLifecycleRuleExecutorMock } from '@kbn/rule-registry-plugin/server/utils/create_lifecycle_rule_executor_mock';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
InventoryMetricConditions,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators, InventoryMetricConditions } from '../../../../common/alerting/metrics';
|
||||
import type { LogMeta, Logger } from '@kbn/logging';
|
||||
import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common';
|
||||
import { createInventoryMetricThresholdExecutor } from './inventory_metric_threshold_executor';
|
||||
|
@ -178,7 +174,7 @@ const baseCriterion = {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
} as InventoryMetricConditions;
|
||||
|
||||
describe('The inventory threshold alert type', () => {
|
||||
|
@ -187,7 +183,7 @@ describe('The inventory threshold alert type', () => {
|
|||
|
||||
setup();
|
||||
|
||||
const execute = (comparator: Comparator, threshold: number[], options?: any) =>
|
||||
const execute = (comparator: COMPARATORS, threshold: number[], options?: any) =>
|
||||
executor({
|
||||
...mockOptions,
|
||||
services,
|
||||
|
@ -215,7 +211,7 @@ describe('The inventory threshold alert type', () => {
|
|||
test('throws error when alertsClient is null', async () => {
|
||||
try {
|
||||
services.alertsClient = null;
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
} catch (e) {
|
||||
expect(e).toMatchInlineSnapshot(
|
||||
'[Error: Expected alertsClient not to be null! There may have been an issue installing alert resources.]'
|
||||
|
@ -232,7 +228,7 @@ describe('The inventory threshold alert type', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0.75],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
shouldFire: true,
|
||||
shouldWarn: false,
|
||||
currentValue: 1.0,
|
||||
|
@ -248,7 +244,7 @@ describe('The inventory threshold alert type', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0.75],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
shouldFire: true,
|
||||
shouldWarn: false,
|
||||
currentValue: 1.0,
|
||||
|
@ -259,7 +255,7 @@ describe('The inventory threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(mostRecentAction(instanceIdA).tags).toStrictEqual([
|
||||
'host-01_tag1',
|
||||
'host-01_tag2',
|
||||
|
@ -282,7 +278,7 @@ describe('The inventory threshold alert type', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0.75],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
shouldFire: true,
|
||||
shouldWarn: false,
|
||||
currentValue: 1.0,
|
||||
|
@ -298,7 +294,7 @@ describe('The inventory threshold alert type', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0.75],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
shouldFire: true,
|
||||
shouldWarn: false,
|
||||
currentValue: 1.0,
|
||||
|
@ -309,7 +305,7 @@ describe('The inventory threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(mostRecentAction(instanceIdA).tags).toStrictEqual(['ruleTag1', 'ruleTag2']);
|
||||
expect(mostRecentAction(instanceIdB).tags).toStrictEqual(['ruleTag1', 'ruleTag2']);
|
||||
});
|
||||
|
@ -329,7 +325,7 @@ describe('The inventory threshold alert type', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [0.75],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
shouldFire: true,
|
||||
shouldWarn: false,
|
||||
currentValue: 1.0,
|
||||
|
@ -340,7 +336,7 @@ describe('The inventory threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
});
|
||||
await execute(Comparator.GT, [0.75], options);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75], options);
|
||||
expect(evaluateConditionFn).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
executionTimestamp: mockedEndDate,
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
AlertInstanceState as AlertState,
|
||||
} from '@kbn/alerting-plugin/common';
|
||||
import { AlertsClientError, RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server';
|
||||
import { getAlertUrl } from '@kbn/observability-plugin/common';
|
||||
import { convertToBuiltInComparators, getAlertUrl } from '@kbn/observability-plugin/common';
|
||||
import { SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { ObservabilityMetricsAlert } from '@kbn/alerts-as-data-utils';
|
||||
import { getOriginalActionGroup } from '../../../utils/get_original_action_group';
|
||||
|
@ -128,7 +128,6 @@ export const createInventoryMetricThresholdExecutor =
|
|||
});
|
||||
|
||||
const indexedStartedAt = start ?? startedAt.toISOString();
|
||||
|
||||
alertsClient.setAlertData({
|
||||
id: UNGROUPED_FACTORY_KEY,
|
||||
payload: {
|
||||
|
@ -403,7 +402,9 @@ const buildReasonWithVerboseMetricName = (
|
|||
: resultItem.metric),
|
||||
currentValue: formatMetric(resultItem.metric, resultItem.currentValue),
|
||||
threshold: formatThreshold(resultItem.metric, thresholdToFormat),
|
||||
comparator: useWarningThreshold ? resultItem.warningComparator! : resultItem.comparator,
|
||||
comparator: useWarningThreshold
|
||||
? convertToBuiltInComparators(resultItem.warningComparator!)
|
||||
: convertToBuiltInComparators(resultItem.comparator),
|
||||
};
|
||||
return buildReason(resultWithVerboseMetricName);
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Comparator, InventoryMetricConditions } from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { InventoryMetricConditions } from '../../../../../common/alerting/metrics';
|
||||
import { createBucketSelector } from './create_bucket_selector';
|
||||
|
||||
describe('createBucketSelector', () => {
|
||||
|
@ -15,9 +15,9 @@ describe('createBucketSelector', () => {
|
|||
timeSize: 5,
|
||||
timeUnit: 'm',
|
||||
threshold: [8],
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
warningThreshold: [16],
|
||||
warningComparator: Comparator.LT_OR_EQ,
|
||||
warningComparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
};
|
||||
expect(createBucketSelector('tx', inventoryMetricConditions)).toEqual({
|
||||
selectedBucket: {
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
*/
|
||||
|
||||
import { SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { Comparator, InventoryMetricConditions } from '../../../../../common/alerting/metrics';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { InventoryMetricConditions } from '../../../../../common/alerting/metrics';
|
||||
import { SnapshotCustomMetricInput } from '../../../../../common/http_api';
|
||||
import { createConditionScript } from './create_condition_script';
|
||||
|
||||
|
@ -34,7 +35,7 @@ export const createBucketSelector = (
|
|||
},
|
||||
script: createConditionScript(
|
||||
condition.warningThreshold as number[],
|
||||
condition.warningComparator as Comparator,
|
||||
convertToBuiltInComparators(condition.warningComparator!),
|
||||
metric
|
||||
),
|
||||
},
|
||||
|
@ -47,7 +48,11 @@ export const createBucketSelector = (
|
|||
buckets_path: {
|
||||
value: metricId,
|
||||
},
|
||||
script: createConditionScript(condition.threshold, condition.comparator, metric),
|
||||
script: createConditionScript(
|
||||
condition.threshold,
|
||||
convertToBuiltInComparators(condition.comparator),
|
||||
metric
|
||||
),
|
||||
},
|
||||
}
|
||||
: EMPTY_SHOULD_WARN;
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Comparator } from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { createConditionScript } from './create_condition_script';
|
||||
|
||||
describe('createConditionScript', () => {
|
||||
it('should convert tx threshold from bits to byte', () => {
|
||||
expect(createConditionScript([8], Comparator.GT_OR_EQ, 'tx')).toEqual({
|
||||
expect(createConditionScript([8], COMPARATORS.GREATER_THAN_OR_EQUALS, 'tx')).toEqual({
|
||||
params: {
|
||||
// Threshold has been converted from 8 bits to 1 byte
|
||||
threshold: 1,
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import { SnapshotMetricType } from '@kbn/metrics-data-access-plugin/common';
|
||||
import { Comparator } from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertMetricValue } from './convert_metric_value';
|
||||
|
||||
export const createConditionScript = (
|
||||
conditionThresholds: number[],
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
metric: SnapshotMetricType
|
||||
) => {
|
||||
const threshold = conditionThresholds.map((n) => convertMetricValue(metric, n));
|
||||
if (comparator === Comparator.BETWEEN && threshold.length === 2) {
|
||||
if (comparator === COMPARATORS.BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 1 : 0`,
|
||||
params: {
|
||||
|
@ -23,9 +23,10 @@ export const createConditionScript = (
|
|||
},
|
||||
};
|
||||
}
|
||||
if (comparator === Comparator.OUTSIDE_RANGE && threshold.length === 2) {
|
||||
|
||||
if (comparator === COMPARATORS.NOT_BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
// OUTSIDE_RANGE/NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
// NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 0 : 1`,
|
||||
params: {
|
||||
threshold0: threshold[0],
|
||||
|
|
|
@ -16,15 +16,14 @@ import {
|
|||
SnapshotMetricType,
|
||||
SnapshotMetricTypeKeys,
|
||||
} from '@kbn/metrics-data-access-plugin/common';
|
||||
import type { InfraConfig } from '../../../../common/plugin_config_types';
|
||||
import {
|
||||
Comparator,
|
||||
METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID,
|
||||
} from '../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { LEGACY_COMPARATORS } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator';
|
||||
import {
|
||||
SnapshotCustomAggregation,
|
||||
SNAPSHOT_CUSTOM_AGGREGATIONS,
|
||||
} from '../../../../common/http_api/snapshot_api';
|
||||
} from '../../../../common/http_api';
|
||||
import type { InfraConfig } from '../../../../common/plugin_config_types';
|
||||
import { METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID } from '../../../../common/alerting/metrics';
|
||||
import { InfraBackendLibs } from '../../infra_types';
|
||||
import {
|
||||
alertDetailUrlActionVariableDescription,
|
||||
|
@ -54,16 +53,15 @@ import {
|
|||
import { MetricsRulesTypeAlertDefinition } from '../register_rule_types';
|
||||
import { O11Y_AAD_FIELDS } from '../../../../common/constants';
|
||||
|
||||
const comparators = Object.values({ ...COMPARATORS, ...LEGACY_COMPARATORS });
|
||||
const condition = schema.object({
|
||||
threshold: schema.arrayOf(schema.number()),
|
||||
comparator: oneOfLiterals(Object.values(Comparator)) as Type<Comparator>,
|
||||
comparator: oneOfLiterals(comparators) as Type<COMPARATORS>,
|
||||
timeUnit: schema.string() as Type<TimeUnitChar>,
|
||||
timeSize: schema.number(),
|
||||
metric: oneOfLiterals(Object.keys(SnapshotMetricTypeKeys)) as Type<SnapshotMetricType>,
|
||||
warningThreshold: schema.maybe(schema.arrayOf(schema.number())),
|
||||
warningComparator: schema.maybe(oneOfLiterals(Object.values(Comparator))) as Type<
|
||||
Comparator | undefined
|
||||
>,
|
||||
warningComparator: schema.maybe(oneOfLiterals(comparators)) as Type<COMPARATORS | undefined>,
|
||||
customMetric: schema.maybe(
|
||||
schema.object({
|
||||
type: schema.literal('custom'),
|
||||
|
|
|
@ -4,12 +4,8 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
MetricExpressionParams,
|
||||
} from '../../../../../common/alerting/metrics';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { Aggregators, MetricExpressionParams } from '../../../../../common/alerting/metrics';
|
||||
import { createConditionScript } from './create_condition_script';
|
||||
import { createLastPeriod } from './wrap_in_period';
|
||||
|
||||
|
@ -49,7 +45,7 @@ export const createBucketSelector = (
|
|||
},
|
||||
script: createConditionScript(
|
||||
condition.warningThreshold as number[],
|
||||
condition.warningComparator as Comparator
|
||||
convertToBuiltInComparators(condition.warningComparator!)
|
||||
),
|
||||
},
|
||||
}
|
||||
|
@ -60,7 +56,10 @@ export const createBucketSelector = (
|
|||
buckets_path: {
|
||||
value: bucketPath,
|
||||
},
|
||||
script: createConditionScript(condition.threshold, condition.comparator),
|
||||
script: createConditionScript(
|
||||
condition.threshold,
|
||||
convertToBuiltInComparators(condition.comparator)
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { Comparator } from '../../../../../common/alerting/metrics';
|
||||
|
||||
export const createConditionScript = (threshold: number[], comparator: Comparator) => {
|
||||
if (comparator === Comparator.BETWEEN && threshold.length === 2) {
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
export const createConditionScript = (threshold: number[], comparator: COMPARATORS) => {
|
||||
if (comparator === COMPARATORS.BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 1 : 0`,
|
||||
params: {
|
||||
|
@ -16,9 +15,9 @@ export const createConditionScript = (threshold: number[], comparator: Comparato
|
|||
},
|
||||
};
|
||||
}
|
||||
if (comparator === Comparator.OUTSIDE_RANGE && threshold.length === 2) {
|
||||
if (comparator === COMPARATORS.NOT_BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
// OUTSIDE_RANGE/NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
// NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 0 : 1`,
|
||||
params: {
|
||||
threshold0: threshold[0],
|
||||
|
|
|
@ -9,11 +9,9 @@ import { SearchResponse, AggregationsAggregate } from '@elastic/elasticsearch/li
|
|||
import { ElasticsearchClient } from '@kbn/core/server';
|
||||
import type { Logger } from '@kbn/logging';
|
||||
import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common/search_strategy';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
MetricExpressionParams,
|
||||
} from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common';
|
||||
import { Aggregators, MetricExpressionParams } from '../../../../../common/alerting/metrics';
|
||||
import {
|
||||
AdditionalContext,
|
||||
doFieldsExist,
|
||||
|
@ -226,10 +224,16 @@ export const getData = async (
|
|||
// the value will end up being ZERO, for other metrics it will be null. In this case
|
||||
// we need to do the evaluation in Node.js
|
||||
if (aggs.all && params.aggType === Aggregators.COUNT && value === 0) {
|
||||
const trigger = comparatorMap[params.comparator](value, params.threshold);
|
||||
const trigger = comparatorMap[convertToBuiltInComparators(params.comparator)](
|
||||
value,
|
||||
params.threshold
|
||||
);
|
||||
const warn =
|
||||
params.warningThreshold && params.warningComparator
|
||||
? comparatorMap[params.warningComparator](value, params.warningThreshold)
|
||||
? comparatorMap[convertToBuiltInComparators(params.warningComparator)](
|
||||
value,
|
||||
params.warningThreshold
|
||||
)
|
||||
: false;
|
||||
return {
|
||||
[UNGROUPED_FACTORY_KEY]: {
|
||||
|
@ -286,13 +290,13 @@ export const getData = async (
|
|||
};
|
||||
|
||||
const comparatorMap = {
|
||||
[Comparator.BETWEEN]: (value: number, [a, b]: number[]) =>
|
||||
[COMPARATORS.BETWEEN]: (value: number, [a, b]: number[]) =>
|
||||
value >= Math.min(a, b) && value <= Math.max(a, b),
|
||||
// `threshold` is always an array of numbers in case the BETWEEN comparator is
|
||||
// used; all other compartors will just destructure the first value in the array
|
||||
[Comparator.GT]: (a: number, [b]: number[]) => a > b,
|
||||
[Comparator.LT]: (a: number, [b]: number[]) => a < b,
|
||||
[Comparator.OUTSIDE_RANGE]: (value: number, [a, b]: number[]) => value < a || value > b,
|
||||
[Comparator.GT_OR_EQ]: (a: number, [b]: number[]) => a >= b,
|
||||
[Comparator.LT_OR_EQ]: (a: number, [b]: number[]) => a <= b,
|
||||
[COMPARATORS.GREATER_THAN]: (a: number, [b]: number[]) => a > b,
|
||||
[COMPARATORS.LESS_THAN]: (a: number, [b]: number[]) => a < b,
|
||||
[COMPARATORS.NOT_BETWEEN]: (value: number, [a, b]: number[]) => value < a || value > b,
|
||||
[COMPARATORS.GREATER_THAN_OR_EQUALS]: (a: number, [b]: number[]) => a >= b,
|
||||
[COMPARATORS.LESS_THAN_OR_EQUALS]: (a: number, [b]: number[]) => a <= b,
|
||||
};
|
||||
|
|
|
@ -6,11 +6,8 @@
|
|||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
MetricExpressionParams,
|
||||
} from '../../../../../common/alerting/metrics';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators, MetricExpressionParams } from '../../../../../common/alerting/metrics';
|
||||
import { getElasticsearchMetricQuery } from './metric_query';
|
||||
|
||||
describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => {
|
||||
|
@ -20,7 +17,7 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => {
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
};
|
||||
|
||||
const groupBy = 'host.doggoname';
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -20,11 +20,12 @@ import {
|
|||
RecoveredActionGroup,
|
||||
} from '@kbn/alerting-plugin/common';
|
||||
import { AlertsClientError, RuleExecutorOptions, RuleTypeState } from '@kbn/alerting-plugin/server';
|
||||
import type { TimeUnitChar } from '@kbn/observability-plugin/common';
|
||||
import { getAlertUrl } from '@kbn/observability-plugin/common';
|
||||
import { TimeUnitChar, getAlertUrl } from '@kbn/observability-plugin/common';
|
||||
import { ObservabilityMetricsAlert } from '@kbn/alerts-as-data-utils';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertToBuiltInComparators } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator';
|
||||
import { getOriginalActionGroup } from '../../../utils/get_original_action_group';
|
||||
import { AlertStates, Comparator } from '../../../../common/alerting/metrics';
|
||||
import { AlertStates } from '../../../../common/alerting/metrics';
|
||||
import { createFormatter } from '../../../../common/formatters';
|
||||
import { InfraBackendLibs } from '../../infra_types';
|
||||
import {
|
||||
|
@ -296,7 +297,16 @@ export const createMetricThresholdExecutor =
|
|||
reason = alertResults
|
||||
.map((result) =>
|
||||
buildFiredAlertReason({
|
||||
...formatAlertResult(result[group], nextState === AlertStates.WARNING),
|
||||
...formatAlertResult(
|
||||
{
|
||||
...result[group],
|
||||
comparator: convertToBuiltInComparators(result[group].comparator),
|
||||
warningComparator: result[group].comparator
|
||||
? convertToBuiltInComparators(result[group].comparator)
|
||||
: undefined,
|
||||
},
|
||||
nextState === AlertStates.WARNING
|
||||
),
|
||||
group,
|
||||
})
|
||||
)
|
||||
|
@ -367,21 +377,33 @@ export const createMetricThresholdExecutor =
|
|||
}),
|
||||
reason,
|
||||
threshold: mapToConditionsLookup(alertResults, (result, index) => {
|
||||
const evaluation = result[group];
|
||||
const evaluation = result[group] as Evaluation;
|
||||
if (!evaluation) {
|
||||
return criteria[index].threshold;
|
||||
}
|
||||
return formatAlertResult(evaluation).threshold;
|
||||
return formatAlertResult({
|
||||
...evaluation,
|
||||
comparator: convertToBuiltInComparators(evaluation.comparator),
|
||||
warningComparator: evaluation.warningComparator
|
||||
? convertToBuiltInComparators(evaluation.warningComparator)
|
||||
: undefined,
|
||||
}).threshold;
|
||||
}),
|
||||
timestamp,
|
||||
value: mapToConditionsLookup(alertResults, (result, index) => {
|
||||
const evaluation = result[group];
|
||||
const evaluation = result[group] as Evaluation;
|
||||
if (!evaluation && criteria[index].aggType === 'count') {
|
||||
return 0;
|
||||
} else if (!evaluation) {
|
||||
return null;
|
||||
}
|
||||
return formatAlertResult(evaluation).currentValue;
|
||||
return formatAlertResult({
|
||||
...evaluation,
|
||||
comparator: convertToBuiltInComparators(evaluation.comparator),
|
||||
warningComparator: evaluation.warningComparator
|
||||
? convertToBuiltInComparators(evaluation.warningComparator)
|
||||
: undefined,
|
||||
}).currentValue;
|
||||
}),
|
||||
viewInAppUrl: getMetricsViewInAppUrlWithSpaceId({
|
||||
basePath: libs.basePath,
|
||||
|
@ -518,9 +540,9 @@ const formatAlertResult = <AlertResult>(
|
|||
metric: string;
|
||||
currentValue: number | null;
|
||||
threshold: number[];
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
warningThreshold?: number[];
|
||||
warningComparator?: Comparator;
|
||||
warningComparator?: COMPARATORS;
|
||||
timeSize: number;
|
||||
timeUnit: TimeUnitChar;
|
||||
} & AlertResult,
|
||||
|
@ -544,7 +566,7 @@ const formatAlertResult = <AlertResult>(
|
|||
threshold: Array.isArray(thresholdToFormat)
|
||||
? thresholdToFormat.map((v: number) => formatter(v))
|
||||
: formatter(thresholdToFormat),
|
||||
comparator: comparatorToUse,
|
||||
comparator: convertToBuiltInComparators(comparatorToUse),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,12 @@
|
|||
import { DEFAULT_APP_CATEGORIES } from '@kbn/core/server';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ActionGroupIdsOf } from '@kbn/alerting-plugin/common';
|
||||
import {
|
||||
GetViewInAppRelativeUrlFnOpts,
|
||||
PluginSetupContract,
|
||||
RuleType,
|
||||
} from '@kbn/alerting-plugin/server';
|
||||
import { GetViewInAppRelativeUrlFnOpts, PluginSetupContract } from '@kbn/alerting-plugin/server';
|
||||
import { observabilityPaths } from '@kbn/observability-plugin/common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { LEGACY_COMPARATORS } from '@kbn/observability-plugin/common/utils/convert_legacy_outside_comparator';
|
||||
import type { InfraConfig } from '../../../../common/plugin_config_types';
|
||||
import { Comparator, METRIC_THRESHOLD_ALERT_TYPE_ID } from '../../../../common/alerting/metrics';
|
||||
import { METRIC_THRESHOLD_ALERT_TYPE_ID } from '../../../../common/alerting/metrics';
|
||||
import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/http_api';
|
||||
import { InfraBackendLibs } from '../../infra_types';
|
||||
import {
|
||||
|
@ -48,13 +45,6 @@ import {
|
|||
import { MetricsRulesTypeAlertDefinition } from '../register_rule_types';
|
||||
import { O11Y_AAD_FIELDS } from '../../../../common/constants';
|
||||
|
||||
type MetricThresholdAllowedActionGroups = ActionGroupIdsOf<
|
||||
typeof FIRED_ACTIONS | typeof WARNING_ACTIONS | typeof NO_DATA_ACTIONS
|
||||
>;
|
||||
export type MetricThresholdAlertType = Omit<RuleType, 'ActionGroupIdsOf'> & {
|
||||
ActionGroupIdsOf: MetricThresholdAllowedActionGroups;
|
||||
};
|
||||
|
||||
export function registerMetricThresholdRuleType(
|
||||
alertingPlugin: PluginSetupContract,
|
||||
libs: InfraBackendLibs,
|
||||
|
@ -63,14 +53,14 @@ export function registerMetricThresholdRuleType(
|
|||
if (!featureFlags.metricThresholdAlertRuleEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const comparator = Object.values({ ...COMPARATORS, ...LEGACY_COMPARATORS });
|
||||
const baseCriterion = {
|
||||
threshold: schema.arrayOf(schema.number()),
|
||||
comparator: oneOfLiterals(Object.values(Comparator)),
|
||||
comparator: oneOfLiterals(comparator),
|
||||
timeUnit: schema.string(),
|
||||
timeSize: schema.number(),
|
||||
warningThreshold: schema.maybe(schema.arrayOf(schema.number())),
|
||||
warningComparator: schema.maybe(oneOfLiterals(Object.values(Comparator))),
|
||||
warningComparator: schema.maybe(oneOfLiterals(comparator)),
|
||||
};
|
||||
|
||||
const nonCountCriterion = schema.object({
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
"@kbn/dashboard-plugin",
|
||||
"@kbn/shared-svg",
|
||||
"@kbn/aiops-log-rate-analysis",
|
||||
"@kbn/search-types",
|
||||
"@kbn/alerting-comparators",
|
||||
"@kbn/react-hooks",
|
||||
"@kbn/search-types",
|
||||
"@kbn/router-utils",
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
import * as rt from 'io-ts';
|
||||
import { DataViewSpec, SerializedSearchSourceFields } from '@kbn/data-plugin/common';
|
||||
import { Filter, Query } from '@kbn/es-query';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { LEGACY_COMPARATORS } from '../utils/convert_legacy_outside_comparator';
|
||||
import { TimeUnitChar } from '../utils/formatters/duration';
|
||||
|
||||
export const ThresholdFormatterTypeRT = rt.keyof({
|
||||
|
@ -20,15 +22,6 @@ export const ThresholdFormatterTypeRT = rt.keyof({
|
|||
});
|
||||
export type ThresholdFormatterType = rt.TypeOf<typeof ThresholdFormatterTypeRT>;
|
||||
|
||||
export enum Comparator {
|
||||
GT = '>',
|
||||
LT = '<',
|
||||
GT_OR_EQ = '>=',
|
||||
LT_OR_EQ = '<=',
|
||||
BETWEEN = 'between',
|
||||
OUTSIDE_RANGE = 'outside',
|
||||
}
|
||||
|
||||
export enum Aggregators {
|
||||
COUNT = 'count',
|
||||
AVERAGE = 'avg',
|
||||
|
@ -78,9 +71,7 @@ export interface BaseMetricExpressionParams {
|
|||
timeUnit: TimeUnitChar;
|
||||
sourceId?: string;
|
||||
threshold: number[];
|
||||
comparator: Comparator;
|
||||
warningComparator?: Comparator;
|
||||
warningThreshold?: number[];
|
||||
comparator: COMPARATORS | LEGACY_COMPARATORS;
|
||||
}
|
||||
|
||||
export interface CustomThresholdExpressionMetric {
|
||||
|
|
|
@ -10,3 +10,46 @@ import { i18n } from '@kbn/i18n';
|
|||
export const NOT_AVAILABLE_LABEL = i18n.translate('xpack.observability.notAvailable', {
|
||||
defaultMessage: 'N/A',
|
||||
});
|
||||
|
||||
// Comparators
|
||||
export const BELOW_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.below',
|
||||
{
|
||||
defaultMessage: 'below',
|
||||
}
|
||||
);
|
||||
|
||||
export const BELOW_OR_EQ_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.belowOrEqual',
|
||||
{
|
||||
defaultMessage: 'below or equal',
|
||||
}
|
||||
);
|
||||
|
||||
export const ABOVE_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.above',
|
||||
{
|
||||
defaultMessage: 'above',
|
||||
}
|
||||
);
|
||||
|
||||
export const ABOVE_OR_EQ_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.aboveOrEqual',
|
||||
{
|
||||
defaultMessage: 'above or equal',
|
||||
}
|
||||
);
|
||||
|
||||
export const BETWEEN_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.between',
|
||||
{
|
||||
defaultMessage: 'between',
|
||||
}
|
||||
);
|
||||
|
||||
export const NOT_BETWEEN_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.notBetween',
|
||||
{
|
||||
defaultMessage: 'not between',
|
||||
}
|
||||
);
|
||||
|
|
|
@ -18,7 +18,7 @@ export {
|
|||
} from './utils/formatters';
|
||||
export { getInspectResponse } from './utils/get_inspect_response';
|
||||
export { getAlertDetailsUrl, getAlertUrl } from './utils/alerting/alert_url';
|
||||
|
||||
export { convertToBuiltInComparators } from './utils/convert_legacy_outside_comparator';
|
||||
export { ProcessorEvent } from './processor_event';
|
||||
|
||||
export {
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 {
|
||||
convertToBuiltInComparators,
|
||||
LEGACY_COMPARATORS,
|
||||
} from './convert_legacy_outside_comparator';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
describe('convertToBuiltInComparators', () => {
|
||||
it('should return in between when passing the legacy outside', () => {
|
||||
const comparator = convertToBuiltInComparators(LEGACY_COMPARATORS.OUTSIDE_RANGE);
|
||||
expect(comparator).toBe(COMPARATORS.NOT_BETWEEN);
|
||||
});
|
||||
|
||||
it('should return the same comparator when NOT passing the legacy outside', () => {
|
||||
const comparator = convertToBuiltInComparators(COMPARATORS.GREATER_THAN);
|
||||
expect(comparator).toBe(COMPARATORS.GREATER_THAN);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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 { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export enum LEGACY_COMPARATORS {
|
||||
OUTSIDE_RANGE = 'outside',
|
||||
}
|
||||
export type LegacyComparator = COMPARATORS | LEGACY_COMPARATORS;
|
||||
|
||||
export function convertToBuiltInComparators(comparator: LegacyComparator): COMPARATORS {
|
||||
if (comparator === LEGACY_COMPARATORS.OUTSIDE_RANGE) return COMPARATORS.NOT_BETWEEN;
|
||||
return comparator;
|
||||
}
|
|
@ -103,13 +103,13 @@ describe('Map rules params with flyout', () => {
|
|||
excludeHitsFromPreviousRun: false,
|
||||
},
|
||||
'kibana.alert.evaluation.value': 100870655162.18182,
|
||||
'kibana.alert.evaluation.threshold': 1,
|
||||
'kibana.alert.evaluation.threshold': [1],
|
||||
},
|
||||
},
|
||||
results: [
|
||||
{
|
||||
observedValue: [100870655162.18182],
|
||||
threshold: [1],
|
||||
threshold: '1',
|
||||
comparator: '>',
|
||||
pctAboveThreshold: ' (10087065516118.18% above the threshold)',
|
||||
},
|
||||
|
@ -149,7 +149,7 @@ describe('Map rules params with flyout', () => {
|
|||
observedValue: [4577],
|
||||
threshold: [100],
|
||||
comparator: 'more than',
|
||||
pctAboveThreshold: ' (4477% above the threshold)',
|
||||
pctAboveThreshold: ' (4477% more than the threshold)',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -215,12 +215,50 @@ describe('Map rules params with flyout', () => {
|
|||
results: [
|
||||
{
|
||||
observedValue: '10.4 Mbit',
|
||||
threshold: ['3 Mbit'],
|
||||
threshold: '3 Mbit',
|
||||
comparator: '>',
|
||||
pctAboveThreshold: ' (247.54% above the threshold)',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
ruleType: 'metrics.alert.inventory.threshold',
|
||||
alert: {
|
||||
fields: {
|
||||
'kibana.alert.rule.rule_type_id': 'metrics.alert.inventory.threshold',
|
||||
'kibana.alert.rule.parameters': {
|
||||
nodeType: 'host',
|
||||
criteria: [
|
||||
{
|
||||
metric: 'rx',
|
||||
comparator: '<',
|
||||
threshold: [90],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
customMetric: {
|
||||
type: 'custom',
|
||||
id: 'alert-custom-metric',
|
||||
field: 'system.memory.used.pct',
|
||||
aggregation: 'avg',
|
||||
},
|
||||
},
|
||||
],
|
||||
sourceId: 'default',
|
||||
},
|
||||
|
||||
'kibana.alert.evaluation.value': [130.4],
|
||||
'kibana.alert.evaluation.threshold': 3000000,
|
||||
},
|
||||
},
|
||||
results: [
|
||||
{
|
||||
comparator: '<',
|
||||
observedValue: '13,040%',
|
||||
pctAboveThreshold: ' (14388.89% below the threshold)',
|
||||
threshold: '9,000%',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
ruleType: 'apm.error_rate',
|
||||
alert: {
|
||||
|
|
|
@ -19,7 +19,15 @@ import {
|
|||
} from '@kbn/rule-data-utils';
|
||||
import { EsQueryRuleParams } from '@kbn/stack-alerts-plugin/public/rule_types/es_query/types';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { asDuration, asPercent } from '../../../../common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
import {
|
||||
ABOVE_OR_EQ_TEXT,
|
||||
ABOVE_TEXT,
|
||||
BELOW_OR_EQ_TEXT,
|
||||
BELOW_TEXT,
|
||||
} from '../../../../common/i18n';
|
||||
import { asDuration, asPercent, convertToBuiltInComparators } from '../../../../common';
|
||||
import { createFormatter } from '../../../../common/custom_threshold_rule/formatters';
|
||||
import { metricValueFormatter } from '../../../../common/custom_threshold_rule/metric_value_formatter';
|
||||
import { METRIC_FORMATTERS } from '../../../../common/custom_threshold_rule/formatters/snapshot_metric_formats';
|
||||
|
@ -37,12 +45,34 @@ export interface FlyoutThresholdData {
|
|||
pctAboveThreshold: string;
|
||||
}
|
||||
|
||||
const getPctAboveThreshold = (observedValue?: number, threshold?: number[]): string => {
|
||||
const getI18nComparator = (comparator?: COMPARATORS) => {
|
||||
switch (comparator) {
|
||||
case COMPARATORS.GREATER_THAN:
|
||||
return ABOVE_TEXT;
|
||||
case COMPARATORS.GREATER_THAN_OR_EQUALS:
|
||||
return ABOVE_OR_EQ_TEXT;
|
||||
case COMPARATORS.LESS_THAN:
|
||||
return BELOW_TEXT;
|
||||
case COMPARATORS.LESS_THAN_OR_EQUALS:
|
||||
return BELOW_OR_EQ_TEXT;
|
||||
default:
|
||||
return comparator;
|
||||
}
|
||||
};
|
||||
const getPctAboveThreshold = (
|
||||
threshold: number[],
|
||||
comparator: COMPARATORS,
|
||||
observedValue?: number
|
||||
): string => {
|
||||
if (!observedValue || !threshold || threshold.length > 1 || threshold[0] <= 0) return '';
|
||||
|
||||
return i18n.translate('xpack.observability.alertFlyout.overview.aboveThresholdLabel', {
|
||||
defaultMessage: ' ({pctValue}% above the threshold)',
|
||||
defaultMessage: ' ({pctValue}% {comparator} the threshold)',
|
||||
values: {
|
||||
pctValue: parseFloat((((observedValue - threshold[0]) * 100) / threshold[0]).toFixed(2)),
|
||||
pctValue: Math.abs(
|
||||
parseFloat((((observedValue - threshold[0]) * 100) / threshold[0]).toFixed(2))
|
||||
),
|
||||
comparator: getI18nComparator(convertToBuiltInComparators(comparator)),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
@ -78,7 +108,11 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
observedValue: formattedValue,
|
||||
threshold: thresholdFormattedAsString,
|
||||
comparator,
|
||||
pctAboveThreshold: getPctAboveThreshold(observedValue, threshold),
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
threshold,
|
||||
convertToBuiltInComparators(comparator),
|
||||
observedValue
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
});
|
||||
|
||||
|
@ -113,46 +147,82 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
observedValue: formattedValue,
|
||||
threshold: thresholdFormattedAsString,
|
||||
comparator,
|
||||
pctAboveThreshold: getPctAboveThreshold(observedValue, threshold),
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
threshold,
|
||||
convertToBuiltInComparators(comparator),
|
||||
observedValue
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
});
|
||||
|
||||
case METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID:
|
||||
return observedValues.map((observedValue, metricIndex) => {
|
||||
const criteria = ruleCriteria[metricIndex] as BaseMetricExpressionParams & {
|
||||
const { threshold, customMetric, metric, comparator } = ruleCriteria[
|
||||
metricIndex
|
||||
] as BaseMetricExpressionParams & {
|
||||
metric: string;
|
||||
customMetric: {
|
||||
field: string;
|
||||
};
|
||||
};
|
||||
const infraType = METRIC_FORMATTERS[criteria.metric].formatter;
|
||||
const formatter = createFormatter(infraType);
|
||||
const comparator = criteria.comparator;
|
||||
const threshold = criteria.threshold;
|
||||
const formatThreshold = threshold.map((v: number) => {
|
||||
if (infraType === 'percent') {
|
||||
v = Number(v) / 100;
|
||||
const metricField = customMetric?.field || metric;
|
||||
const thresholdFormatted = threshold.map((thresholdToFormat) => {
|
||||
if (
|
||||
metricField.endsWith('.pct') ||
|
||||
(METRIC_FORMATTERS[metric] && METRIC_FORMATTERS[metric].formatter === 'percent')
|
||||
) {
|
||||
thresholdToFormat = thresholdToFormat / 100;
|
||||
} else if (
|
||||
metricField.endsWith('.bytes') ||
|
||||
(METRIC_FORMATTERS[metric] && METRIC_FORMATTERS[metric].formatter === 'bits')
|
||||
) {
|
||||
thresholdToFormat = thresholdToFormat / 8;
|
||||
}
|
||||
if (infraType === 'bits') {
|
||||
v = Number(v) / 8;
|
||||
}
|
||||
return v;
|
||||
return thresholdToFormat;
|
||||
});
|
||||
|
||||
let observedValueFormatted: string;
|
||||
let thresholdFormattedAsString: string;
|
||||
if (customMetric.field) {
|
||||
observedValueFormatted = metricValueFormatter(
|
||||
observedValue as number,
|
||||
customMetric.field
|
||||
);
|
||||
thresholdFormattedAsString = threshold
|
||||
.map((thresholdToStringFormat) =>
|
||||
metricValueFormatter(thresholdToStringFormat, metricField)
|
||||
)
|
||||
.join(' AND ');
|
||||
} else {
|
||||
const infraType = METRIC_FORMATTERS[metric].formatter;
|
||||
const formatter = createFormatter(infraType);
|
||||
observedValueFormatted = formatter(observedValue);
|
||||
thresholdFormattedAsString = thresholdFormatted.map(formatter).join(' AND ');
|
||||
}
|
||||
|
||||
return {
|
||||
observedValue: formatter(observedValue),
|
||||
threshold: formatThreshold.map(formatter),
|
||||
observedValue: observedValueFormatted,
|
||||
threshold: thresholdFormattedAsString,
|
||||
comparator,
|
||||
pctAboveThreshold: getPctAboveThreshold(observedValue, formatThreshold),
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
thresholdFormatted,
|
||||
convertToBuiltInComparators(comparator),
|
||||
observedValue
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
});
|
||||
|
||||
case LOG_THRESHOLD_ALERT_TYPE_ID:
|
||||
const { comparator } = ruleParams?.count as { comparator: string };
|
||||
const { comparator } = ruleParams?.count as { comparator: COMPARATORS };
|
||||
const flyoutMap = {
|
||||
observedValue: [alert.fields[ALERT_EVALUATION_VALUE]],
|
||||
threshold: [alert.fields[ALERT_EVALUATION_THRESHOLD]],
|
||||
comparator,
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
[alert.fields[ALERT_EVALUATION_THRESHOLD]!],
|
||||
comparator,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [flyoutMap];
|
||||
|
||||
|
@ -160,10 +230,12 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
const APMFlyoutMapErrorCount = {
|
||||
observedValue: [alert.fields[ALERT_EVALUATION_VALUE]],
|
||||
threshold: [alert.fields[ALERT_EVALUATION_THRESHOLD]],
|
||||
comparator: '>',
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
[alert.fields[ALERT_EVALUATION_THRESHOLD]!],
|
||||
COMPARATORS.GREATER_THAN,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [APMFlyoutMapErrorCount];
|
||||
|
||||
|
@ -171,10 +243,12 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
const APMFlyoutMapTransactionErrorRate = {
|
||||
observedValue: [asPercent(alert.fields[ALERT_EVALUATION_VALUE], 100)],
|
||||
threshold: [asPercent(alert.fields[ALERT_EVALUATION_THRESHOLD], 100)],
|
||||
comparator: '>',
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
[alert.fields[ALERT_EVALUATION_THRESHOLD]!],
|
||||
COMPARATORS.GREATER_THAN,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [APMFlyoutMapTransactionErrorRate];
|
||||
|
||||
|
@ -182,22 +256,26 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
const APMFlyoutMapTransactionDuration = {
|
||||
observedValue: [asDuration(alert.fields[ALERT_EVALUATION_VALUE])],
|
||||
threshold: [asDuration(alert.fields[ALERT_EVALUATION_THRESHOLD])],
|
||||
comparator: '>',
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
[alert.fields[ALERT_EVALUATION_THRESHOLD]!],
|
||||
COMPARATORS.GREATER_THAN,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [APMFlyoutMapTransactionDuration];
|
||||
|
||||
case '.es-query':
|
||||
const { thresholdComparator } = ruleParams as EsQueryRuleParams;
|
||||
const { thresholdComparator, threshold } = ruleParams as EsQueryRuleParams;
|
||||
const ESQueryFlyoutMap = {
|
||||
observedValue: [alert.fields[ALERT_EVALUATION_VALUE]],
|
||||
threshold: [alert.fields[ALERT_EVALUATION_THRESHOLD]],
|
||||
threshold: threshold.join(' AND '),
|
||||
comparator: thresholdComparator,
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
threshold,
|
||||
thresholdComparator as COMPARATORS,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [ESQueryFlyoutMap];
|
||||
|
||||
|
@ -205,10 +283,12 @@ export const mapRuleParamsWithFlyout = (alert: TopAlert): FlyoutThresholdData[]
|
|||
const SLOBurnRateFlyoutMap = {
|
||||
observedValue: [alert.fields[ALERT_EVALUATION_VALUE]],
|
||||
threshold: [alert.fields[ALERT_EVALUATION_THRESHOLD]],
|
||||
comparator: '>',
|
||||
pctAboveThreshold: getPctAboveThreshold(alert.fields[ALERT_EVALUATION_VALUE], [
|
||||
alert.fields[ALERT_EVALUATION_THRESHOLD]!,
|
||||
]),
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
pctAboveThreshold: getPctAboveThreshold(
|
||||
[alert.fields[ALERT_EVALUATION_THRESHOLD]!],
|
||||
COMPARATORS.GREATER_THAN,
|
||||
alert.fields[ALERT_EVALUATION_VALUE]
|
||||
),
|
||||
} as unknown as FlyoutThresholdData;
|
||||
return [SLOBurnRateFlyoutMap];
|
||||
default:
|
||||
|
|
|
@ -13,6 +13,8 @@ import { AlertStatus } from '@kbn/rule-data-utils';
|
|||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { Tooltip as CaseTooltip } from '@kbn/cases-components';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { LEGACY_COMPARATORS } from '../../../common/utils/convert_legacy_outside_comparator';
|
||||
import type { Group } from '../../../common/custom_threshold_rule/types';
|
||||
import { NavigateToCaseView } from '../../hooks/use_case_view_navigation';
|
||||
import { Groups } from '../custom_threshold/components/alert_details_app_section/groups';
|
||||
|
@ -124,11 +126,18 @@ export const overviewColumns: Array<EuiBasicTableColumn<AlertOverviewField>> = [
|
|||
return (
|
||||
<div>
|
||||
{ruleCriteria.map((criteria, criticalIndex) => {
|
||||
const threshold = criteria.threshold;
|
||||
const comparator = criteria.comparator;
|
||||
const { threshold, comparator } = criteria;
|
||||
let formattedComparator = comparator.toUpperCase();
|
||||
if (
|
||||
comparator === COMPARATORS.NOT_BETWEEN ||
|
||||
comparator === LEGACY_COMPARATORS.OUTSIDE_RANGE
|
||||
) {
|
||||
// No need for i18n as we are using the enum value, we only need a space.
|
||||
formattedComparator = 'NOT BETWEEN';
|
||||
}
|
||||
return (
|
||||
<EuiText size="s" key={`${threshold}-${criticalIndex}`}>
|
||||
<h4>{`${comparator.toUpperCase()} ${threshold}`}</h4>
|
||||
<h4>{`${formattedComparator} ${threshold}`}</h4>
|
||||
</EuiText>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Aggregators, Comparator } from '../../../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators } from '../../../../../../common/custom_threshold_rule/types';
|
||||
import { CustomThresholdRuleTypeParams } from '../../../types';
|
||||
import { getLogRateAnalysisEQQuery } from './log_rate_analysis_query';
|
||||
|
||||
|
@ -29,7 +30,7 @@ describe('buildEsQuery', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [90],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
@ -85,7 +86,7 @@ describe('buildEsQuery', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [90],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -108,7 +109,7 @@ describe('buildEsQuery', () => {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
threshold: [90],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
import { Color } from '../../../../../common/custom_threshold_rule/color_palette';
|
||||
import { Comparator } from '../../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
|
||||
|
@ -30,7 +30,7 @@ describe('ThresholdAnnotations', () => {
|
|||
const defaultProps = {
|
||||
threshold: [20, 30],
|
||||
sortedThresholds: [20, 30],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
color: Color.color0,
|
||||
id: 'testId',
|
||||
firstTimestamp: 123456789,
|
||||
|
@ -54,7 +54,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for in between thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.BETWEEN });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="between-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -73,7 +73,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render an upper rectangular annotation for outside range thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.OUTSIDE_RANGE });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.NOT_BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="outside-range-lower-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -92,7 +92,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a lower rectangular annotation for outside range thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.OUTSIDE_RANGE });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.NOT_BETWEEN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="outside-range-upper-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -111,7 +111,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for below thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.LT });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.LESS_THAN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="below-rect"]');
|
||||
const expectedValues = [
|
||||
|
@ -130,7 +130,7 @@ describe('ThresholdAnnotations', () => {
|
|||
});
|
||||
|
||||
it('should render a rectangular annotation for above thresholds', async () => {
|
||||
const wrapper = await setup({ comparator: Comparator.GT });
|
||||
const wrapper = await setup({ comparator: COMPARATORS.GREATER_THAN });
|
||||
|
||||
const annotation = wrapper.find('[data-test-subj="above-rect"]');
|
||||
const expectedValues = [
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
import { AnnotationDomainType, LineAnnotation, RectAnnotation } from '@elastic/charts';
|
||||
import { first, last } from 'lodash';
|
||||
import React from 'react';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Color, colorTransformer } from '../../../../../common/custom_threshold_rule/color_palette';
|
||||
import { Comparator } from '../../../../../common/custom_threshold_rule/types';
|
||||
|
||||
interface ThresholdAnnotationsProps {
|
||||
threshold: number[];
|
||||
sortedThresholds: number[];
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
color: Color;
|
||||
id: string;
|
||||
firstTimestamp: number;
|
||||
|
@ -34,8 +34,10 @@ export function ThresholdAnnotations({
|
|||
domain,
|
||||
}: ThresholdAnnotationsProps) {
|
||||
if (!comparator || !threshold) return null;
|
||||
const isAbove = [Comparator.GT, Comparator.GT_OR_EQ].includes(comparator);
|
||||
const isBelow = [Comparator.LT, Comparator.LT_OR_EQ].includes(comparator);
|
||||
const isAbove = [COMPARATORS.GREATER_THAN, COMPARATORS.GREATER_THAN_OR_EQUALS].includes(
|
||||
comparator
|
||||
);
|
||||
const isBelow = [COMPARATORS.LESS_THAN, COMPARATORS.LESS_THAN_OR_EQUALS].includes(comparator);
|
||||
return (
|
||||
<>
|
||||
<LineAnnotation
|
||||
|
@ -53,7 +55,7 @@ export function ThresholdAnnotations({
|
|||
},
|
||||
}}
|
||||
/>
|
||||
{sortedThresholds.length === 2 && comparator === Comparator.BETWEEN ? (
|
||||
{sortedThresholds.length === 2 && comparator === COMPARATORS.BETWEEN ? (
|
||||
<>
|
||||
<RectAnnotation
|
||||
id={`${id}-lower-threshold`}
|
||||
|
@ -75,7 +77,7 @@ export function ThresholdAnnotations({
|
|||
/>
|
||||
</>
|
||||
) : null}
|
||||
{sortedThresholds.length === 2 && comparator === Comparator.OUTSIDE_RANGE ? (
|
||||
{sortedThresholds.length === 2 && comparator === COMPARATORS.NOT_BETWEEN ? (
|
||||
<>
|
||||
<RectAnnotation
|
||||
id={`${id}-lower-threshold`}
|
||||
|
|
|
@ -9,10 +9,10 @@ import { Meta, Story } from '@storybook/react/types-6-0';
|
|||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { decorateWithGlobalStorybookThemeProviders } from '../../../../test_utils/use_global_storybook_theme';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
import { TimeUnitChar } from '../../../../../common';
|
||||
|
@ -102,7 +102,7 @@ const BASE_ARGS: Partial<CustomEquationEditorProps> = {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm' as TimeUnitChar,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
fields: [
|
||||
{ name: 'system.cpu.user.pct', normalizedType: 'number' },
|
||||
|
@ -128,7 +128,7 @@ CustomEquationEditorWithEquationErrors.args = {
|
|||
timeSize: 1,
|
||||
timeUnit: 'm' as TimeUnitChar,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
errors: {
|
||||
equation:
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
import React from 'react';
|
||||
import { ComponentMeta } from '@storybook/react';
|
||||
import { LIGHT_THEME } from '@elastic/charts';
|
||||
|
||||
import { Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Props, Threshold as Component } from './custom_threshold';
|
||||
|
||||
export default {
|
||||
|
@ -31,7 +30,7 @@ export default {
|
|||
|
||||
const defaultProps: Props = {
|
||||
chartProps: { baseTheme: LIGHT_THEME },
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
id: 'componentId',
|
||||
threshold: [90],
|
||||
title: 'Threshold breached',
|
||||
|
|
|
@ -10,13 +10,13 @@ import { LIGHT_THEME } from '@elastic/charts';
|
|||
import { render } from '@testing-library/react';
|
||||
import { Props, Threshold } from './custom_threshold';
|
||||
import React from 'react';
|
||||
import { Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
describe('Threshold', () => {
|
||||
const renderComponent = (props: Partial<Props> = {}) => {
|
||||
const defaultProps: Props = {
|
||||
chartProps: { baseTheme: LIGHT_THEME },
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
id: 'componentId',
|
||||
threshold: [90],
|
||||
title: 'Threshold breached',
|
||||
|
@ -43,7 +43,7 @@ describe('Threshold', () => {
|
|||
|
||||
it('shows component for between', () => {
|
||||
const component = renderComponent({
|
||||
comparator: Comparator.BETWEEN,
|
||||
comparator: COMPARATORS.BETWEEN,
|
||||
threshold: [90, 95],
|
||||
});
|
||||
expect(component.queryByTestId('thresholdRule-90-95-93')).toBeTruthy();
|
||||
|
|
|
@ -10,7 +10,7 @@ import { Chart, Metric, Settings } from '@elastic/charts';
|
|||
import { EuiIcon, EuiPanel, useEuiBackgroundColor } from '@elastic/eui';
|
||||
import type { PartialTheme, Theme } from '@elastic/charts';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export interface ChartProps {
|
||||
theme?: PartialTheme;
|
||||
|
@ -19,7 +19,7 @@ export interface ChartProps {
|
|||
|
||||
export interface Props {
|
||||
chartProps: ChartProps;
|
||||
comparator: Comparator | string;
|
||||
comparator: COMPARATORS | string;
|
||||
id: string;
|
||||
threshold: number[];
|
||||
title: string;
|
||||
|
|
|
@ -9,9 +9,10 @@ import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
|||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '../../../../common/custom_threshold_rule/types';
|
||||
import { MetricExpression } from '../types';
|
||||
import { ExpressionRow } from './expression_row';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
describe('ExpressionRow', () => {
|
||||
async function setup(expression: MetricExpression) {
|
||||
|
@ -57,7 +58,7 @@ describe('ExpressionRow', () => {
|
|||
|
||||
it('should display thresholds as a percentage for pct metrics', async () => {
|
||||
const expression: MetricExpression = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
@ -82,7 +83,7 @@ describe('ExpressionRow', () => {
|
|||
|
||||
it('should display thresholds as a decimal for all other metrics', async () => {
|
||||
const expression = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
|
|
@ -18,35 +18,20 @@ import { i18n } from '@kbn/i18n';
|
|||
import React, { useCallback, useMemo, useState, ReactElement } from 'react';
|
||||
import {
|
||||
AggregationType,
|
||||
builtInComparators,
|
||||
COMPARATORS,
|
||||
IErrorObject,
|
||||
ThresholdExpression,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { DataViewBase, DataViewFieldBase } from '@kbn/es-query';
|
||||
import { debounce } from 'lodash';
|
||||
import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { convertToBuiltInComparators } from '../../../../common/utils/convert_legacy_outside_comparator';
|
||||
import { Aggregators } from '../../../../common/custom_threshold_rule/types';
|
||||
import { MetricExpression } from '../types';
|
||||
import { CustomEquationEditor } from './custom_equation';
|
||||
import { CUSTOM_EQUATION, LABEL_HELP_MESSAGE, LABEL_LABEL } from '../i18n_strings';
|
||||
import { decimalToPct, pctToDecimal } from '../helpers/corrected_percent_convert';
|
||||
import { isPercent } from '../helpers/threshold_unit';
|
||||
|
||||
// Create a new object with COMPARATORS.NOT_BETWEEN removed as we use OUTSIDE_RANGE
|
||||
const updatedBuiltInComparators = { ...builtInComparators };
|
||||
delete updatedBuiltInComparators[COMPARATORS.NOT_BETWEEN];
|
||||
|
||||
const customComparators = {
|
||||
...updatedBuiltInComparators,
|
||||
[Comparator.OUTSIDE_RANGE]: {
|
||||
text: i18n.translate('xpack.observability.customThreshold.rule.alertFlyout.outsideRangeLabel', {
|
||||
defaultMessage: 'Is not between',
|
||||
}),
|
||||
value: Comparator.OUTSIDE_RANGE,
|
||||
requiredValues: 2,
|
||||
},
|
||||
};
|
||||
|
||||
interface ExpressionRowProps {
|
||||
title: ReactElement;
|
||||
fields: DataViewFieldBase[];
|
||||
|
@ -76,14 +61,13 @@ export const ExpressionRow: React.FC<ExpressionRowProps> = (props) => {
|
|||
title,
|
||||
} = props;
|
||||
|
||||
const { metrics, comparator = Comparator.GT, threshold = [] } = expression;
|
||||
|
||||
const { metrics, comparator = COMPARATORS.GREATER_THAN, threshold = [] } = expression;
|
||||
const isMetricPct = useMemo(() => isPercent(metrics), [metrics]);
|
||||
const [label, setLabel] = useState<string | undefined>(expression?.label || undefined);
|
||||
|
||||
const updateComparator = useCallback(
|
||||
(c?: string) => {
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as Comparator });
|
||||
setRuleParams(expressionId, { ...expression, comparator: c as COMPARATORS });
|
||||
},
|
||||
[expressionId, expression, setRuleParams]
|
||||
);
|
||||
|
@ -214,12 +198,17 @@ const ThresholdElement: React.FC<{
|
|||
return threshold;
|
||||
}, [threshold, isMetricPct]);
|
||||
|
||||
const thresholdComparator = useCallback(() => {
|
||||
if (!comparator) return COMPARATORS.GREATER_THAN;
|
||||
// Check if the rule had a legacy OUTSIDE_RANGE inside its params.
|
||||
// Then, change it on-the-fly to NOT_BETWEEN
|
||||
return convertToBuiltInComparators(comparator);
|
||||
}, [comparator]);
|
||||
return (
|
||||
<>
|
||||
<ThresholdExpression
|
||||
thresholdComparator={comparator || Comparator.GT}
|
||||
thresholdComparator={thresholdComparator()}
|
||||
threshold={displayedThreshold}
|
||||
customComparators={customComparators}
|
||||
onChangeSelectedThresholdComparator={updateComparator}
|
||||
onChangeSelectedThreshold={updateThreshold}
|
||||
errors={errors}
|
||||
|
|
|
@ -9,8 +9,8 @@ import React from 'react';
|
|||
import { act } from 'react-dom/test-utils';
|
||||
import { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Comparator,
|
||||
Aggregators,
|
||||
CustomThresholdSearchSourceFields,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
|
@ -69,7 +69,7 @@ describe('Rule condition chart', () => {
|
|||
timeUnit: 'm',
|
||||
sourceId: 'default',
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
};
|
||||
const { wrapper } = await setup(expression);
|
||||
expect(wrapper.find('[data-test-subj="thresholdRuleNoChartData"]').exists()).toBeTruthy();
|
||||
|
|
|
@ -25,11 +25,9 @@ import { IErrorObject } from '@kbn/triggers-actions-ui-plugin/public';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { TimeRange } from '@kbn/es-query';
|
||||
import { EventAnnotationConfig } from '@kbn/event-annotation-common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { EventsAsUnit } from '../../../../../common/constants';
|
||||
import {
|
||||
Comparator,
|
||||
CustomThresholdSearchSourceFields,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
import { CustomThresholdSearchSourceFields } from '../../../../../common/custom_threshold_rule/types';
|
||||
import { useKibana } from '../../../../utils/kibana_react';
|
||||
import { MetricExpression } from '../../types';
|
||||
import { AggMap, PainlessTinyMathParser } from './painless_tinymath_parser';
|
||||
|
@ -121,15 +119,15 @@ export function RuleConditionChart({
|
|||
const refLayers = [];
|
||||
|
||||
if (
|
||||
comparator === Comparator.OUTSIDE_RANGE ||
|
||||
(comparator === Comparator.BETWEEN && threshold.length === 2)
|
||||
comparator === COMPARATORS.NOT_BETWEEN ||
|
||||
(comparator === COMPARATORS.BETWEEN && threshold.length === 2)
|
||||
) {
|
||||
const refLineStart = new XYReferenceLinesLayer({
|
||||
data: [
|
||||
{
|
||||
value: (threshold[0] || 0).toString(),
|
||||
color: euiTheme.colors.danger,
|
||||
fill: comparator === Comparator.OUTSIDE_RANGE ? 'below' : 'none',
|
||||
fill: comparator === COMPARATORS.NOT_BETWEEN ? 'below' : 'none',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -138,7 +136,7 @@ export function RuleConditionChart({
|
|||
{
|
||||
value: (threshold[1] || 0).toString(),
|
||||
color: euiTheme.colors.danger,
|
||||
fill: comparator === Comparator.OUTSIDE_RANGE ? 'above' : 'none',
|
||||
fill: comparator === COMPARATORS.NOT_BETWEEN ? 'above' : 'none',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
@ -146,7 +144,7 @@ export function RuleConditionChart({
|
|||
refLayers.push(refLineStart, refLineEnd);
|
||||
} else {
|
||||
let fill: FillStyle = 'above';
|
||||
if (comparator === Comparator.LT || comparator === Comparator.LT_OR_EQ) {
|
||||
if (comparator === COMPARATORS.LESS_THAN || comparator === COMPARATORS.LESS_THAN_OR_EQUALS) {
|
||||
fill = 'below';
|
||||
}
|
||||
const thresholdRefLine = new XYReferenceLinesLayer({
|
||||
|
|
|
@ -11,8 +11,8 @@ import { buildEsQuery, fromKueryExpression } from '@kbn/es-query';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import { ValidationResult } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
CustomThresholdSearchSourceFields,
|
||||
} from '../../../../common/custom_threshold_rule/types';
|
||||
|
@ -111,7 +111,7 @@ export function validateCustomThreshold({
|
|||
// The Threshold component returns an empty array with a length ([empty]) because it's using delete newThreshold[i].
|
||||
// We need to use [...c.threshold] to convert it to an array with an undefined value ([undefined]) so we can test each element.
|
||||
const { comparator, threshold } = { comparator: c.comparator, threshold: c.threshold } as {
|
||||
comparator?: Comparator;
|
||||
comparator?: COMPARATORS;
|
||||
threshold?: number[];
|
||||
};
|
||||
if (threshold && threshold.length && ![...threshold].every(isNumber)) {
|
||||
|
@ -130,7 +130,7 @@ export function validateCustomThreshold({
|
|||
});
|
||||
}
|
||||
|
||||
if (comparator === Comparator.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
if (comparator === COMPARATORS.BETWEEN && (!threshold || threshold.length < 2)) {
|
||||
errors[id].critical.threshold1.push(
|
||||
i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.alertFlyout.error.thresholdRequired',
|
||||
|
|
|
@ -13,7 +13,8 @@ import { queryClient } from '@kbn/osquery-plugin/public/query_client';
|
|||
import { mountWithIntl, nextTick } from '@kbn/test-jest-helpers';
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { Aggregators, Comparator } from '../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { Aggregators } from '../../../common/custom_threshold_rule/types';
|
||||
import { useKibana } from '../../utils/kibana_react';
|
||||
import { kibanaStartMock } from '../../utils/kibana_react.mock';
|
||||
import Expressions from './custom_threshold_rule_expression';
|
||||
|
@ -152,7 +153,7 @@ describe('Expression', () => {
|
|||
aggType: Aggregators.COUNT,
|
||||
},
|
||||
],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [100],
|
||||
timeSize: 1,
|
||||
timeUnit: 'm',
|
||||
|
@ -178,7 +179,7 @@ describe('Expression', () => {
|
|||
{ name: 'A', aggType: Aggregators.AVERAGE, field: 'system.load.1' },
|
||||
{ name: 'B', aggType: Aggregators.CARDINALITY, field: 'system.cpu.user.pct' },
|
||||
],
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
equation: 'A * B',
|
||||
label: 'prefill label',
|
||||
threshold: [500],
|
||||
|
@ -200,7 +201,7 @@ describe('Expression', () => {
|
|||
{ name: 'A', aggType: Aggregators.AVERAGE, field: 'system.load.1' },
|
||||
{ name: 'B', aggType: Aggregators.CARDINALITY, field: 'system.cpu.user.pct' },
|
||||
],
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
equation: 'A * B',
|
||||
label: 'prefill label',
|
||||
threshold: [500],
|
||||
|
|
|
@ -36,8 +36,9 @@ import {
|
|||
RuleTypeParamsExpressionProps,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { useKibana } from '../../utils/kibana_react';
|
||||
import { Aggregators, Comparator } from '../../../common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '../../../common/custom_threshold_rule/types';
|
||||
import { TimeUnitChar } from '../../../common/utils/formatters/duration';
|
||||
import { AlertContextMeta, AlertParams, MetricExpression } from './types';
|
||||
import { ExpressionRow } from './components/expression_row';
|
||||
|
@ -53,7 +54,7 @@ type Props = Omit<
|
|||
>;
|
||||
|
||||
export const defaultExpression: MetricExpression = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { CustomThresholdAlertFields } from '../types';
|
||||
import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '../../../../common/custom_threshold_rule/types';
|
||||
|
||||
import { CustomThresholdAlert, CustomThresholdRule } from '../components/types';
|
||||
|
||||
|
@ -60,7 +61,7 @@ export const buildCustomThresholdRule = (
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
@ -72,7 +73,7 @@ export const buildCustomThresholdRule = (
|
|||
timeUnit: 'm',
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'B',
|
||||
|
@ -83,11 +84,9 @@ export const buildCustomThresholdRule = (
|
|||
threshold: [4],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
warningComparator: Comparator.GT,
|
||||
warningThreshold: [2.2],
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'C',
|
||||
|
@ -100,7 +99,7 @@ export const buildCustomThresholdRule = (
|
|||
timeUnit: 'm',
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
@ -115,7 +114,7 @@ export const buildCustomThresholdRule = (
|
|||
'A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A + A',
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'C',
|
||||
|
@ -133,7 +132,7 @@ export const buildCustomThresholdRule = (
|
|||
timeUnit: 'm',
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'CAD',
|
||||
|
@ -209,7 +208,7 @@ export const buildCustomThresholdAlert = (
|
|||
'kibana.alert.rule.parameters': {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'A',
|
||||
|
@ -222,7 +221,7 @@ export const buildCustomThresholdAlert = (
|
|||
timeUnit: 'm',
|
||||
},
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
name: 'B',
|
||||
|
@ -233,7 +232,7 @@ export const buildCustomThresholdAlert = (
|
|||
threshold: [4],
|
||||
timeSize: 15,
|
||||
timeUnit: 'm',
|
||||
warningComparator: Comparator.GT,
|
||||
warningComparator: COMPARATORS.GREATER_THAN,
|
||||
warningThreshold: [2.2],
|
||||
},
|
||||
],
|
||||
|
|
|
@ -194,7 +194,6 @@ export function RuleDetailsPage() {
|
|||
: '';
|
||||
|
||||
if (isLoading || isRuleDeleting) return <CenterJustifiedSpinner />;
|
||||
|
||||
if (!rule || isError) return <NoRuleFoundPanel />;
|
||||
|
||||
return (
|
||||
|
|
|
@ -13,9 +13,9 @@ import { FIRED_ACTION, NO_DATA_ACTION } from './constants';
|
|||
import { Evaluation } from './lib/evaluate_rule';
|
||||
import type { LogMeta, Logger } from '@kbn/logging';
|
||||
import { DEFAULT_FLAPPING_SETTINGS } from '@kbn/alerting-plugin/common';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
CustomThresholdExpressionMetric,
|
||||
} from '../../../../common/custom_threshold_rule/types';
|
||||
|
@ -234,7 +234,7 @@ describe('The custom threshold alert type', () => {
|
|||
beforeEach(() => jest.clearAllMocks());
|
||||
afterAll(() => clearInstances());
|
||||
const instanceID = '*';
|
||||
const execute = (comparator: Comparator, threshold: number[], sourceId: string = 'default') =>
|
||||
const execute = (comparator: COMPARATORS, threshold: number[], sourceId: string = 'default') =>
|
||||
executor({
|
||||
...mockOptions,
|
||||
services,
|
||||
|
@ -251,7 +251,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
});
|
||||
const setResults = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
shouldFire: boolean = false,
|
||||
isNoData: boolean = false
|
||||
|
@ -271,62 +271,62 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
test('alerts as expected with the > comparator', async () => {
|
||||
setResults(Comparator.GT, [0.75], true);
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
setResults(COMPARATORS.GREATER_THAN, [0.75], true);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.GT, [1.5], false);
|
||||
await execute(Comparator.GT, [1.5]);
|
||||
setResults(COMPARATORS.GREATER_THAN, [1.5], false);
|
||||
await execute(COMPARATORS.GREATER_THAN, [1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts as expected with the < comparator', async () => {
|
||||
setResults(Comparator.LT, [1.5], true);
|
||||
await execute(Comparator.LT, [1.5]);
|
||||
setResults(COMPARATORS.LESS_THAN, [1.5], true);
|
||||
await execute(COMPARATORS.LESS_THAN, [1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.LT, [0.75], false);
|
||||
await execute(Comparator.LT, [0.75]);
|
||||
setResults(COMPARATORS.LESS_THAN, [0.75], false);
|
||||
await execute(COMPARATORS.LESS_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts as expected with the >= comparator', async () => {
|
||||
setResults(Comparator.GT_OR_EQ, [0.75], true);
|
||||
await execute(Comparator.GT_OR_EQ, [0.75]);
|
||||
setResults(COMPARATORS.GREATER_THAN_OR_EQUALS, [0.75], true);
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.GT_OR_EQ, [1.0], true);
|
||||
await execute(Comparator.GT_OR_EQ, [1.0]);
|
||||
setResults(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.0], true);
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.0]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.GT_OR_EQ, [1.5], false);
|
||||
await execute(Comparator.GT_OR_EQ, [1.5]);
|
||||
setResults(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.5], false);
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts as expected with the <= comparator', async () => {
|
||||
setResults(Comparator.LT_OR_EQ, [1.5], true);
|
||||
await execute(Comparator.LT_OR_EQ, [1.5]);
|
||||
setResults(COMPARATORS.LESS_THAN_OR_EQUALS, [1.5], true);
|
||||
await execute(COMPARATORS.LESS_THAN_OR_EQUALS, [1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.LT_OR_EQ, [1.0], true);
|
||||
await execute(Comparator.LT_OR_EQ, [1.0]);
|
||||
setResults(COMPARATORS.LESS_THAN_OR_EQUALS, [1.0], true);
|
||||
await execute(COMPARATORS.LESS_THAN_OR_EQUALS, [1.0]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.LT_OR_EQ, [0.75], false);
|
||||
await execute(Comparator.LT_OR_EQ, [0.75]);
|
||||
setResults(COMPARATORS.LESS_THAN_OR_EQUALS, [0.75], false);
|
||||
await execute(COMPARATORS.LESS_THAN_OR_EQUALS, [0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts as expected with the between comparator', async () => {
|
||||
setResults(Comparator.BETWEEN, [0, 1.5], true);
|
||||
await execute(Comparator.BETWEEN, [0, 1.5]);
|
||||
setResults(COMPARATORS.BETWEEN, [0, 1.5], true);
|
||||
await execute(COMPARATORS.BETWEEN, [0, 1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.BETWEEN, [0, 0.75], false);
|
||||
await execute(Comparator.BETWEEN, [0, 0.75]);
|
||||
setResults(COMPARATORS.BETWEEN, [0, 0.75], false);
|
||||
await execute(COMPARATORS.BETWEEN, [0, 0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts as expected with the outside range comparator', async () => {
|
||||
setResults(Comparator.OUTSIDE_RANGE, [0, 0.75], true);
|
||||
await execute(Comparator.OUTSIDE_RANGE, [0, 0.75]);
|
||||
test('alerts as expected with the not between comparator', async () => {
|
||||
setResults(COMPARATORS.NOT_BETWEEN, [0, 0.75], true);
|
||||
await execute(COMPARATORS.NOT_BETWEEN, [0, 0.75]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setResults(Comparator.OUTSIDE_RANGE, [0, 1.5], false);
|
||||
await execute(Comparator.OUTSIDE_RANGE, [0, 1.5]);
|
||||
setResults(COMPARATORS.NOT_BETWEEN, [0, 1.5], false);
|
||||
await execute(COMPARATORS.NOT_BETWEEN, [0, 1.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('reports expected values to the action context', async () => {
|
||||
setResults(Comparator.GT, [0.75], true);
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
setResults(COMPARATORS.GREATER_THAN, [0.75], true);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
const reportedAlert = getLastReportedAlert(instanceID);
|
||||
expect(reportedAlert?.context?.group).toBeUndefined();
|
||||
expect(reportedAlert?.context?.reason).toBe(
|
||||
|
@ -339,7 +339,7 @@ describe('The custom threshold alert type', () => {
|
|||
beforeEach(() => jest.clearAllMocks());
|
||||
afterAll(() => clearInstances());
|
||||
const execute = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
groupBy: string[] = ['groupByField'],
|
||||
metrics?: CustomThresholdExpressionMetric[],
|
||||
|
@ -369,7 +369,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -379,7 +379,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -389,7 +389,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceIdA)).toHaveAlertAction();
|
||||
expect(getLastReportedAlert(instanceIdB)).toHaveAlertAction();
|
||||
});
|
||||
|
@ -398,7 +398,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1.5],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -408,7 +408,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1.5],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -418,7 +418,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.LT, [1.5]);
|
||||
await execute(COMPARATORS.LESS_THAN, [1.5]);
|
||||
expect(getLastReportedAlert(instanceIdA)).toHaveAlertAction();
|
||||
expect(getLastReportedAlert(instanceIdB)).toBe(undefined);
|
||||
});
|
||||
|
@ -427,7 +427,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [5],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -437,7 +437,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [5],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -447,7 +447,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.GT, [5]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [5]);
|
||||
expect(getLastReportedAlert(instanceIdA)).toBe(undefined);
|
||||
expect(getLastReportedAlert(instanceIdB)).toBe(undefined);
|
||||
});
|
||||
|
@ -456,7 +456,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -466,7 +466,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -476,7 +476,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceIdA)?.context?.group).toEqual([
|
||||
{ field: 'groupByField', value: 'a' },
|
||||
]);
|
||||
|
@ -489,7 +489,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -506,7 +506,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -523,7 +523,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -541,7 +541,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult1 } = await execute(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
['groupByField'],
|
||||
[
|
||||
|
@ -557,7 +557,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -567,7 +567,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -577,7 +577,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -588,7 +588,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult2 } = await execute(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
['groupByField'],
|
||||
[
|
||||
|
@ -607,7 +607,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -617,7 +617,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -628,7 +628,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult3 } = await execute(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
['groupByField', 'groupByField-else'],
|
||||
[
|
||||
|
@ -644,7 +644,7 @@ describe('The custom threshold alert type', () => {
|
|||
});
|
||||
|
||||
const executeWithFilter = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
filterQuery: string,
|
||||
metrics?: any,
|
||||
|
@ -679,7 +679,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -696,7 +696,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -713,7 +713,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -731,7 +731,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult1 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'q' }),
|
||||
'test.metric.2'
|
||||
|
@ -741,7 +741,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -751,7 +751,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -761,7 +761,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -772,7 +772,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult2 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'q' }),
|
||||
'test.metric.1',
|
||||
|
@ -785,7 +785,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -795,7 +795,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -806,7 +806,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult3 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'different' }),
|
||||
[
|
||||
|
@ -825,7 +825,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -842,7 +842,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -859,7 +859,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -877,7 +877,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult1 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'q' }),
|
||||
'test.metric.2'
|
||||
|
@ -887,7 +887,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -897,7 +897,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -907,7 +907,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -918,7 +918,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const { state: stateResult2 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'q' }),
|
||||
'test.metric.1',
|
||||
|
@ -934,7 +934,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -944,7 +944,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: null,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -957,7 +957,7 @@ describe('The custom threshold alert type', () => {
|
|||
// Consider c as untracked
|
||||
services.alertsClient.isTrackedAlert.mockImplementation((id: string) => id !== 'c');
|
||||
const { state: stateResult3 } = await executeWithFilter(
|
||||
Comparator.GT,
|
||||
COMPARATORS.GREATER_THAN,
|
||||
[0.75],
|
||||
JSON.stringify({ query: 'q' }),
|
||||
'test.metric.1',
|
||||
|
@ -973,7 +973,7 @@ describe('The custom threshold alert type', () => {
|
|||
describe('querying with a groupBy parameter host.name and rule tags', () => {
|
||||
afterAll(() => clearInstances());
|
||||
const execute = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
groupBy: string[] = ['host.name'],
|
||||
metrics?: any,
|
||||
|
@ -1008,7 +1008,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'host-01': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1021,7 +1021,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
'host-02': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1034,7 +1034,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceIdA)?.context?.tags).toStrictEqual([
|
||||
'host-01_tag1',
|
||||
'host-01_tag2',
|
||||
|
@ -1053,7 +1053,7 @@ describe('The custom threshold alert type', () => {
|
|||
describe('querying without a groupBy parameter and rule tags', () => {
|
||||
afterAll(() => clearInstances());
|
||||
const execute = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
groupBy: string = '',
|
||||
metrics?: any,
|
||||
|
@ -1086,7 +1086,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1098,7 +1098,7 @@ describe('The custom threshold alert type', () => {
|
|||
]);
|
||||
|
||||
const instanceID = '*';
|
||||
await execute(Comparator.GT, [0.75]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.75]);
|
||||
expect(getLastReportedAlert(instanceID)?.context?.tags).toStrictEqual([
|
||||
'ruleTag1',
|
||||
'ruleTag2',
|
||||
|
@ -1109,7 +1109,7 @@ describe('The custom threshold alert type', () => {
|
|||
describe('querying with multiple criteria', () => {
|
||||
afterAll(() => clearInstances());
|
||||
const execute = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
thresholdA: number[],
|
||||
thresholdB: number[],
|
||||
groupBy: string = '',
|
||||
|
@ -1148,7 +1148,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [1.0],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1160,7 +1160,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [3.0],
|
||||
currentValue: 3.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1171,7 +1171,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const instanceID = '*';
|
||||
await execute(Comparator.GT_OR_EQ, [1.0], [3.0]);
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.0], [3.0]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
});
|
||||
test('sends no alert when some, but not all, criteria cross the threshold', async () => {
|
||||
|
@ -1179,7 +1179,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [1.0],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1191,7 +1191,7 @@ describe('The custom threshold alert type', () => {
|
|||
{},
|
||||
]);
|
||||
const instanceID = '*';
|
||||
await execute(Comparator.LT_OR_EQ, [1.0], [2.5]);
|
||||
await execute(COMPARATORS.LESS_THAN_OR_EQUALS, [1.0], [2.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
test('alerts only on groups that meet all criteria when querying with a groupBy parameter', async () => {
|
||||
|
@ -1199,7 +1199,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [1.0],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1209,7 +1209,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [1.0],
|
||||
currentValue: 3.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1221,7 +1221,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [3.0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1238,7 +1238,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [3.0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1257,7 +1257,7 @@ describe('The custom threshold alert type', () => {
|
|||
]);
|
||||
const instanceIdA = 'a';
|
||||
const instanceIdB = 'b';
|
||||
await execute(Comparator.GT_OR_EQ, [1.0], [3.0], 'groupByField');
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.0], [3.0], 'groupByField');
|
||||
expect(getLastReportedAlert(instanceIdA)).toHaveAlertAction();
|
||||
expect(getLastReportedAlert(instanceIdB)).toBe(undefined);
|
||||
});
|
||||
|
@ -1266,7 +1266,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [1.0],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1278,7 +1278,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT_OR_EQ,
|
||||
comparator: COMPARATORS.GREATER_THAN_OR_EQUALS,
|
||||
threshold: [3.0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1296,7 +1296,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
]);
|
||||
const instanceID = '*';
|
||||
await execute(Comparator.GT_OR_EQ, [1.0], [3.0]);
|
||||
await execute(COMPARATORS.GREATER_THAN_OR_EQUALS, [1.0], [3.0]);
|
||||
const reportedAlert = getLastReportedAlert(instanceID);
|
||||
const reasons = reportedAlert?.context?.reason;
|
||||
expect(reasons).toBe(
|
||||
|
@ -1308,7 +1308,7 @@ describe('The custom threshold alert type', () => {
|
|||
describe('querying with the count aggregator', () => {
|
||||
afterAll(() => clearInstances());
|
||||
const instanceID = '*';
|
||||
const execute = (comparator: Comparator, threshold: number[], sourceId: string = 'default') =>
|
||||
const execute = (comparator: COMPARATORS, threshold: number[], sourceId: string = 'default') =>
|
||||
executor({
|
||||
...mockOptions,
|
||||
services,
|
||||
|
@ -1329,7 +1329,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.9],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1339,13 +1339,13 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.GT, [0.9]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.9]);
|
||||
expect(getLastReportedAlert(instanceID)).toHaveAlertAction();
|
||||
setEvaluationResults([
|
||||
{
|
||||
'*': {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [0.5],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1355,12 +1355,12 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await execute(Comparator.LT, [0.5]);
|
||||
await execute(COMPARATORS.LESS_THAN, [0.5]);
|
||||
expect(getLastReportedAlert(instanceID)).toBe(undefined);
|
||||
});
|
||||
describe('with a groupBy parameter', () => {
|
||||
const executeGroupBy = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
sourceId: string = 'default',
|
||||
state?: any
|
||||
|
@ -1390,7 +1390,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [0],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1400,7 +1400,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [0],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1410,14 +1410,14 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
const resultState = await executeGroupBy(Comparator.LT_OR_EQ, [0]);
|
||||
const resultState = await executeGroupBy(COMPARATORS.LESS_THAN_OR_EQUALS, [0]);
|
||||
expect(getLastReportedAlert(instanceIdA)).toBe(undefined);
|
||||
expect(getLastReportedAlert(instanceIdB)).toBe(undefined);
|
||||
setEvaluationResults([
|
||||
{
|
||||
a: {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [0],
|
||||
currentValue: 0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1427,7 +1427,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.LT_OR_EQ,
|
||||
comparator: COMPARATORS.LESS_THAN_OR_EQUALS,
|
||||
threshold: [0],
|
||||
currentValue: 0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1437,7 +1437,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
},
|
||||
]);
|
||||
await executeGroupBy(Comparator.LT_OR_EQ, [0], 'empty-response', resultState);
|
||||
await executeGroupBy(COMPARATORS.LESS_THAN_OR_EQUALS, [0], 'empty-response', resultState);
|
||||
expect(getLastReportedAlert(instanceIdA)).toHaveAlertAction();
|
||||
expect(getLastReportedAlert(instanceIdB)).toHaveAlertAction();
|
||||
});
|
||||
|
@ -1446,7 +1446,7 @@ describe('The custom threshold alert type', () => {
|
|||
|
||||
describe('querying recovered alert with a count aggregator', () => {
|
||||
afterAll(() => clearInstances());
|
||||
const execute = (comparator: Comparator, threshold: number[], sourceId: string = 'default') =>
|
||||
const execute = (comparator: COMPARATORS, threshold: number[], sourceId: string = 'default') =>
|
||||
executor({
|
||||
...mockOptions,
|
||||
services,
|
||||
|
@ -1467,7 +1467,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.9],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1488,7 +1488,7 @@ describe('The custom threshold alert type', () => {
|
|||
]),
|
||||
};
|
||||
});
|
||||
await execute(Comparator.GT, [0.9]);
|
||||
await execute(COMPARATORS.GREATER_THAN, [0.9]);
|
||||
const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||
expect(getViewInAppUrl).toBeCalledWith({
|
||||
dataViewId: 'c34a7c79-a88b-4b4a-ad19-72f6d24104e4',
|
||||
|
@ -1519,7 +1519,7 @@ describe('The custom threshold alert type', () => {
|
|||
criteria: [
|
||||
{
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [1],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1538,7 +1538,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1567,7 +1567,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1602,7 +1602,7 @@ describe('The custom threshold alert type', () => {
|
|||
criteria: [
|
||||
{
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [1],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1614,7 +1614,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
{
|
||||
...customThresholdCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [30],
|
||||
},
|
||||
],
|
||||
|
@ -1626,7 +1626,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.LT,
|
||||
comparator: COMPARATORS.LESS_THAN,
|
||||
threshold: [1],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1675,7 +1675,7 @@ describe('The custom threshold alert type', () => {
|
|||
criteria: [
|
||||
{
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics,
|
||||
},
|
||||
|
@ -1700,7 +1700,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1723,7 +1723,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1746,7 +1746,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1756,7 +1756,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1780,7 +1780,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1797,7 +1797,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1824,7 +1824,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1841,7 +1841,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1858,7 +1858,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
c: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1884,7 +1884,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1894,7 +1894,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -1923,7 +1923,7 @@ describe('The custom threshold alert type', () => {
|
|||
criteria: [
|
||||
{
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics,
|
||||
},
|
||||
|
@ -1944,7 +1944,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1967,7 +1967,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -1990,7 +1990,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 1,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -2000,7 +2000,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
currentValue: 3,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -2022,7 +2022,7 @@ describe('The custom threshold alert type', () => {
|
|||
{
|
||||
a: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -2039,7 +2039,7 @@ describe('The custom threshold alert type', () => {
|
|||
},
|
||||
b: {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0],
|
||||
metrics: [
|
||||
{
|
||||
|
@ -2116,7 +2116,7 @@ declare global {
|
|||
}
|
||||
|
||||
const customThresholdNonCountCriterion: CustomMetricExpressionParams = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
aggType: Aggregators.AVERAGE,
|
||||
|
@ -2131,7 +2131,7 @@ const customThresholdNonCountCriterion: CustomMetricExpressionParams = {
|
|||
|
||||
const mockedCountFilter = 'mockedCountFilter';
|
||||
const customThresholdCountCriterion: CustomMetricExpressionParams = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
aggType: Aggregators.COUNT,
|
||||
|
|
|
@ -33,11 +33,7 @@ import {
|
|||
CustomThresholdActionGroup,
|
||||
CustomThresholdAlert,
|
||||
} from './types';
|
||||
import {
|
||||
buildFiredAlertReason,
|
||||
buildNoDataAlertReason,
|
||||
// buildRecoveredAlertReason,
|
||||
} from './messages';
|
||||
import { buildFiredAlertReason, buildNoDataAlertReason } from './messages';
|
||||
import {
|
||||
createScopedLogger,
|
||||
hasAdditionalContext,
|
||||
|
@ -91,6 +87,7 @@ export const createCustomThresholdExecutor = ({
|
|||
} = options;
|
||||
|
||||
const { criteria } = params;
|
||||
|
||||
if (criteria.length === 0) throw new Error('Cannot execute an alert with 0 conditions');
|
||||
const thresholdLogger = createScopedLogger(logger, 'thresholdRule', {
|
||||
alertId: ruleId,
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { convertToBuiltInComparators } from '../../../../../common';
|
||||
import { CustomMetricExpressionParams } from '../../../../../common/custom_threshold_rule/types';
|
||||
import { createConditionScript } from './create_condition_script';
|
||||
import { createLastPeriod } from './wrap_in_period';
|
||||
|
@ -24,7 +25,10 @@ export const createBucketSelector = (
|
|||
buckets_path: {
|
||||
value: bucketPath,
|
||||
},
|
||||
script: createConditionScript(condition.threshold, condition.comparator),
|
||||
script: createConditionScript(
|
||||
condition.threshold,
|
||||
convertToBuiltInComparators(condition.comparator)
|
||||
),
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Comparator } from '../../../../../common/custom_threshold_rule/types';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export const createConditionScript = (threshold: number[], comparator: Comparator) => {
|
||||
if (comparator === Comparator.BETWEEN && threshold.length === 2) {
|
||||
export const createConditionScript = (threshold: number[], comparator: COMPARATORS) => {
|
||||
if (comparator === COMPARATORS.BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 1 : 0`,
|
||||
params: {
|
||||
|
@ -17,9 +17,9 @@ export const createConditionScript = (threshold: number[], comparator: Comparato
|
|||
},
|
||||
};
|
||||
}
|
||||
if (comparator === Comparator.OUTSIDE_RANGE && threshold.length === 2) {
|
||||
if (comparator === COMPARATORS.NOT_BETWEEN && threshold.length === 2) {
|
||||
return {
|
||||
// OUTSIDE_RANGE/NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
// NOT BETWEEN is the opposite of BETWEEN. Use the BETWEEN condition and switch the 1 and 0
|
||||
source: `params.value > params.threshold0 && params.value < params.threshold1 ? 0 : 1`,
|
||||
params: {
|
||||
threshold0: threshold[0],
|
||||
|
|
|
@ -194,7 +194,6 @@ export const getData = async (
|
|||
const fieldsExisted = groupBy?.includes(KUBERNETES_POD_UID)
|
||||
? await doFieldsExist(esClient, [CONTAINER_ID], index)
|
||||
: null;
|
||||
|
||||
const request = {
|
||||
index,
|
||||
allow_no_indices: true,
|
||||
|
|
|
@ -7,12 +7,12 @@
|
|||
|
||||
import moment from 'moment';
|
||||
import {
|
||||
Comparator,
|
||||
Aggregators,
|
||||
CustomMetricExpressionParams,
|
||||
SearchConfigurationType,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
import { getElasticsearchMetricQuery } from './metric_query';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => {
|
||||
const expressionParams: CustomMetricExpressionParams = {
|
||||
|
@ -26,7 +26,7 @@ describe("The Metric Threshold Alert's getElasticsearchMetricQuery", () => {
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
};
|
||||
const searchConfiguration: SearchConfigurationType = {
|
||||
index: {
|
||||
|
|
|
@ -6,58 +6,58 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { formatDurationFromTimeUnitChar } from '../../../../common';
|
||||
import { Evaluation } from './lib/evaluate_rule';
|
||||
import { formatAlertResult, FormattedEvaluation } from './lib/format_alert_result';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
BELOW_TEXT,
|
||||
ABOVE_TEXT,
|
||||
ABOVE_OR_EQ_TEXT,
|
||||
BELOW_TEXT,
|
||||
BELOW_OR_EQ_TEXT,
|
||||
BETWEEN_TEXT,
|
||||
NOT_BETWEEN_TEXT,
|
||||
CUSTOM_EQUATION_I18N,
|
||||
ABOVE_OR_EQ_TEXT,
|
||||
BELOW_OR_EQ_TEXT,
|
||||
} from './translations';
|
||||
} from '../../../../common/i18n';
|
||||
import { convertToBuiltInComparators, formatDurationFromTimeUnitChar } from '../../../../common';
|
||||
import { Evaluation } from './lib/evaluate_rule';
|
||||
import { formatAlertResult, FormattedEvaluation } from './lib/format_alert_result';
|
||||
import { CUSTOM_EQUATION_I18N } from './translations';
|
||||
import { UNGROUPED_FACTORY_KEY } from './constants';
|
||||
|
||||
const toNumber = (value: number | string) =>
|
||||
typeof value === 'string' ? parseFloat(value) : value;
|
||||
|
||||
const recoveredComparatorToI18n = (
|
||||
comparator: Comparator,
|
||||
comparator: COMPARATORS,
|
||||
threshold: number[],
|
||||
currentValue: number
|
||||
) => {
|
||||
switch (comparator) {
|
||||
case Comparator.BETWEEN:
|
||||
case COMPARATORS.BETWEEN:
|
||||
return currentValue < threshold[0] ? BELOW_TEXT : ABOVE_TEXT;
|
||||
case Comparator.OUTSIDE_RANGE:
|
||||
case COMPARATORS.NOT_BETWEEN:
|
||||
return BETWEEN_TEXT;
|
||||
case Comparator.GT:
|
||||
case COMPARATORS.GREATER_THAN:
|
||||
return ABOVE_TEXT;
|
||||
case Comparator.GT_OR_EQ:
|
||||
case COMPARATORS.GREATER_THAN_OR_EQUALS:
|
||||
return ABOVE_OR_EQ_TEXT;
|
||||
case Comparator.LT:
|
||||
case COMPARATORS.LESS_THAN:
|
||||
return BELOW_TEXT;
|
||||
case Comparator.LT_OR_EQ:
|
||||
case COMPARATORS.LESS_THAN_OR_EQUALS:
|
||||
return BELOW_OR_EQ_TEXT;
|
||||
}
|
||||
};
|
||||
|
||||
const alertComparatorToI18n = (comparator: Comparator) => {
|
||||
const alertComparatorToI18n = (comparator: COMPARATORS) => {
|
||||
switch (comparator) {
|
||||
case Comparator.BETWEEN:
|
||||
case COMPARATORS.BETWEEN:
|
||||
return BETWEEN_TEXT;
|
||||
case Comparator.OUTSIDE_RANGE:
|
||||
case COMPARATORS.NOT_BETWEEN:
|
||||
return NOT_BETWEEN_TEXT;
|
||||
case Comparator.GT:
|
||||
case COMPARATORS.GREATER_THAN:
|
||||
return ABOVE_TEXT;
|
||||
case Comparator.GT_OR_EQ:
|
||||
case COMPARATORS.GREATER_THAN_OR_EQUALS:
|
||||
return ABOVE_OR_EQ_TEXT;
|
||||
case Comparator.LT:
|
||||
case COMPARATORS.LESS_THAN:
|
||||
return BELOW_TEXT;
|
||||
case Comparator.LT_OR_EQ:
|
||||
case COMPARATORS.LESS_THAN_OR_EQUALS:
|
||||
return BELOW_OR_EQ_TEXT;
|
||||
}
|
||||
};
|
||||
|
@ -124,7 +124,7 @@ const buildAggregationReason: (evaluation: FormattedEvaluation) => string = ({
|
|||
defaultMessage: '{label} is {currentValue}, {comparator} the threshold of {threshold}',
|
||||
values: {
|
||||
label,
|
||||
comparator: alertComparatorToI18n(comparator),
|
||||
comparator: alertComparatorToI18n(convertToBuiltInComparators(comparator)),
|
||||
threshold: thresholdToI18n(threshold),
|
||||
currentValue,
|
||||
},
|
||||
|
@ -134,7 +134,7 @@ const buildAggregationReason: (evaluation: FormattedEvaluation) => string = ({
|
|||
export const buildRecoveredAlertReason: (alertResult: {
|
||||
group: string;
|
||||
label?: string;
|
||||
comparator: Comparator;
|
||||
comparator: COMPARATORS;
|
||||
threshold: Array<number | string>;
|
||||
currentValue: number | string;
|
||||
}) => string = ({ group, label = CUSTOM_EQUATION_I18N, comparator, threshold, currentValue }) =>
|
||||
|
|
|
@ -5,15 +5,15 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
import { Evaluation } from '../lib/evaluate_rule';
|
||||
|
||||
const customThresholdNonCountCriterion: CustomMetricExpressionParams = {
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
metrics: [
|
||||
{
|
||||
aggType: Aggregators.AVERAGE,
|
||||
|
@ -30,7 +30,7 @@ export const alertResultsMultipleConditions: Array<Record<string, Evaluation>> =
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 1.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
@ -42,7 +42,7 @@ export const alertResultsMultipleConditions: Array<Record<string, Evaluation>> =
|
|||
{
|
||||
'*': {
|
||||
...customThresholdNonCountCriterion,
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.75],
|
||||
currentValue: 3.0,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
Aggregators,
|
||||
Comparator,
|
||||
CustomMetricExpressionParams,
|
||||
} from '../../../../../common/custom_threshold_rule/types';
|
||||
|
||||
|
@ -28,7 +28,7 @@ export const criteriaMultipleConditions: CustomMetricExpressionParams[] = [
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [1],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
{
|
||||
metrics: [
|
||||
|
@ -46,7 +46,7 @@ export const criteriaMultipleConditions: CustomMetricExpressionParams[] = [
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [4],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -67,7 +67,7 @@ export const criteriaMultipleConditionsWithIsBetween: CustomMetricExpressionPara
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [1, 2],
|
||||
comparator: Comparator.BETWEEN,
|
||||
comparator: COMPARATORS.BETWEEN,
|
||||
},
|
||||
{
|
||||
metrics: [
|
||||
|
@ -85,6 +85,6 @@ export const criteriaMultipleConditionsWithIsBetween: CustomMetricExpressionPara
|
|||
timeUnit: 'm',
|
||||
timeSize: 1,
|
||||
threshold: [4],
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -15,9 +15,11 @@ import { IBasePath, Logger } from '@kbn/core/server';
|
|||
import { legacyExperimentalFieldMap } from '@kbn/alerts-as-data-utils';
|
||||
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils';
|
||||
import { LicenseType } from '@kbn/licensing-plugin/server';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { EsQueryRuleParamsExtractedParams } from '@kbn/stack-alerts-plugin/server/rule_types/es_query/rule_type_params';
|
||||
import { LEGACY_COMPARATORS } from '../../../../common/utils/convert_legacy_outside_comparator';
|
||||
import { observabilityFeatureId, observabilityPaths } from '../../../../common';
|
||||
import { Aggregators, Comparator } from '../../../../common/custom_threshold_rule/types';
|
||||
import { Aggregators } from '../../../../common/custom_threshold_rule/types';
|
||||
import { THRESHOLD_RULE_REGISTRATION_CONTEXT } from '../../../common/constants';
|
||||
|
||||
import {
|
||||
|
@ -75,9 +77,10 @@ export function thresholdRuleType(
|
|||
logger: Logger,
|
||||
locators: CustomThresholdLocators
|
||||
) {
|
||||
const comparators = Object.values({ ...COMPARATORS, ...LEGACY_COMPARATORS });
|
||||
const baseCriterion = {
|
||||
threshold: schema.arrayOf(schema.number()),
|
||||
comparator: oneOfLiterals(Object.values(Comparator)),
|
||||
comparator: oneOfLiterals(comparators),
|
||||
timeUnit: schema.string(),
|
||||
timeSize: schema.number(),
|
||||
};
|
||||
|
|
|
@ -85,50 +85,6 @@ export const CUSTOM_EQUATION_I18N = i18n.translate(
|
|||
}
|
||||
);
|
||||
|
||||
// Comparators
|
||||
|
||||
export const BELOW_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.below',
|
||||
{
|
||||
defaultMessage: 'below',
|
||||
}
|
||||
);
|
||||
|
||||
export const BELOW_OR_EQ_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.belowOrEqual',
|
||||
{
|
||||
defaultMessage: 'below or equal',
|
||||
}
|
||||
);
|
||||
|
||||
export const ABOVE_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.above',
|
||||
{
|
||||
defaultMessage: 'above',
|
||||
}
|
||||
);
|
||||
|
||||
export const ABOVE_OR_EQ_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.aboveOrEqual',
|
||||
{
|
||||
defaultMessage: 'above or equal',
|
||||
}
|
||||
);
|
||||
|
||||
export const BETWEEN_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.between',
|
||||
{
|
||||
defaultMessage: 'between',
|
||||
}
|
||||
);
|
||||
|
||||
export const NOT_BETWEEN_TEXT = i18n.translate(
|
||||
'xpack.observability.customThreshold.rule.threshold.notBetween',
|
||||
{
|
||||
defaultMessage: 'not between',
|
||||
}
|
||||
);
|
||||
|
||||
// Action variable descriptions
|
||||
|
||||
export const groupByKeysActionVariableDescription = i18n.translate(
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
"@kbn/data-view-field-editor-plugin",
|
||||
"@kbn/cases-components",
|
||||
"@kbn/aiops-log-rate-analysis",
|
||||
"@kbn/alerting-comparators",
|
||||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/react-kibana-mount",
|
||||
],
|
||||
|
|
|
@ -5,14 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export enum Comparator {
|
||||
GT = '>',
|
||||
LT = '<',
|
||||
GT_OR_EQ = '>=',
|
||||
LT_OR_EQ = '<=',
|
||||
BETWEEN = 'between',
|
||||
OUTSIDE_RANGE = 'outside',
|
||||
}
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
|
||||
export enum Aggregators {
|
||||
COUNT = 'count',
|
||||
|
@ -49,7 +42,7 @@ export const customThresholdAIAssistantLogCount = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [10],
|
||||
timeSize: 2,
|
||||
timeUnit: 'h',
|
||||
|
@ -82,7 +75,7 @@ export const customThresholdAIAssistantMetricAvg = {
|
|||
params: {
|
||||
criteria: [
|
||||
{
|
||||
comparator: Comparator.GT,
|
||||
comparator: COMPARATORS.GREATER_THAN,
|
||||
threshold: [0.5],
|
||||
timeSize: 2,
|
||||
timeUnit: 'h',
|
||||
|
|
|
@ -68,7 +68,8 @@
|
|||
"@kbn/serverless",
|
||||
"@kbn/task-manager-plugin",
|
||||
"@kbn/cloud-plugin",
|
||||
"@kbn/observability-plugin"
|
||||
"@kbn/observability-plugin",
|
||||
"@kbn/alerting-comparators"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -31,11 +31,11 @@
|
|||
"@kbn/logging",
|
||||
"@kbn/securitysolution-io-ts-utils",
|
||||
"@kbn/share-plugin",
|
||||
"@kbn/alerting-state-types",
|
||||
"@kbn/alerts-as-data-utils",
|
||||
"@kbn/core-http-router-server-mocks",
|
||||
"@kbn/core-http-server",
|
||||
"@kbn/search-types",
|
||||
"@kbn/alerting-state-types"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { COMPARATORS } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
export const DEFAULT_VALUES = {
|
||||
THRESHOLD_COMPARATOR: COMPARATORS.GREATER_THAN,
|
||||
QUERY: `{
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
builtInComparators,
|
||||
builtInAggregationTypes,
|
||||
builtInGroupByTypes,
|
||||
COMPARATORS,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import {
|
||||
MAX_SELECTABLE_SOURCE_FIELDS,
|
||||
MAX_SELECTABLE_GROUP_BY_TERMS,
|
||||
|
|
|
@ -20,7 +20,6 @@ import { HttpSetup } from '@kbn/core/public';
|
|||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import {
|
||||
getFields,
|
||||
COMPARATORS,
|
||||
builtInComparators,
|
||||
OfExpression,
|
||||
ThresholdExpression,
|
||||
|
@ -30,6 +29,7 @@ import {
|
|||
builtInAggregationTypes,
|
||||
RuleTypeParamsExpressionProps,
|
||||
} from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { COMPARATORS } from '@kbn/alerting-comparators';
|
||||
import { ThresholdVisualization } from './visualization';
|
||||
import { IndexThresholdRuleParams } from './types';
|
||||
import './expression.scss';
|
||||
|
|
|
@ -33,7 +33,8 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { ChartsPluginSetup } from '@kbn/charts-plugin/public';
|
||||
import { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { AggregationType, Comparator } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import { AggregationType } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import type { Comparator } from '@kbn/alerting-comparators';
|
||||
import { parseDuration } from '@kbn/alerting-plugin/common/parse_duration';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"@kbn/esql-utils",
|
||||
"@kbn/data-view-utils",
|
||||
"@kbn/search-types",
|
||||
"@kbn/alerting-comparators"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
"common/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/alerting-state-types",
|
||||
"@kbn/core",
|
||||
"@kbn/usage-collection-plugin",
|
||||
"@kbn/config-schema",
|
||||
|
@ -22,7 +21,8 @@
|
|||
"@kbn/core-saved-objects-common",
|
||||
"@kbn/core-saved-objects-utils-server",
|
||||
"@kbn/core-test-helpers-kbn-server",
|
||||
"@kbn/core-saved-objects-server"
|
||||
"@kbn/core-saved-objects-server",
|
||||
"@kbn/alerting-state-types"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue