Skip to content

Commit

Permalink
[Logs UI] Log threshold ratio alerts (#76867) (#78852)
Browse files Browse the repository at this point in the history
* Add ratio alerting to log threshold alerts

* Fix i18n

* Move grouped query must not filtering from outer to inner clause

* Use new ratio alerting layout

* Use better defaults for ratio alerts

* Remove div wrapper

* Remove type casting, use user-defined type guards

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Kerry Gallagher <k.gallagher.05@gmail.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 29, 2020
1 parent 1f560c1 commit f5d57d3
Show file tree
Hide file tree
Showing 26 changed files with 1,133 additions and 545 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@
*/
import { i18n } from '@kbn/i18n';
import * as rt from 'io-ts';
import { commonSearchSuccessResponseFieldsRT } from '../../utils/elasticsearch_runtime_types';
import { commonSearchSuccessResponseFieldsRT } from '../../../utils/elasticsearch_runtime_types';

export const LOG_DOCUMENT_COUNT_ALERT_TYPE_ID = 'logs.alert.document.count';

const ThresholdTypeRT = rt.keyof({
count: null,
ratio: null,
});

export type ThresholdType = rt.TypeOf<typeof ThresholdTypeRT>;

// Comparators //
export enum Comparator {
GT = 'more than',
GT_OR_EQ = 'more than or equals',
Expand Down Expand Up @@ -82,19 +90,20 @@ export const ComparatorToi18nMap = {
),
};

// Alert parameters //
export enum AlertStates {
OK,
ALERT,
NO_DATA,
ERROR,
}

const DocumentCountRT = rt.type({
const ThresholdRT = rt.type({
comparator: ComparatorRT,
value: rt.number,
});

export type DocumentCount = rt.TypeOf<typeof DocumentCountRT>;
export type Threshold = rt.TypeOf<typeof ThresholdRT>;

export const CriterionRT = rt.type({
field: rt.string,
Expand All @@ -104,6 +113,13 @@ export const CriterionRT = rt.type({

export type Criterion = rt.TypeOf<typeof CriterionRT>;
export const criteriaRT = rt.array(CriterionRT);
export type Criteria = rt.TypeOf<typeof criteriaRT>;

export const countCriteriaRT = criteriaRT;
export type CountCriteria = rt.TypeOf<typeof countCriteriaRT>;

export const ratioCriteriaRT = rt.tuple([criteriaRT, criteriaRT]);
export type RatioCriteria = rt.TypeOf<typeof ratioCriteriaRT>;

export const TimeUnitRT = rt.union([
rt.literal('s'),
Expand All @@ -116,25 +132,73 @@ export type TimeUnit = rt.TypeOf<typeof TimeUnitRT>;
export const timeSizeRT = rt.number;
export const groupByRT = rt.array(rt.string);

export const LogDocumentCountAlertParamsRT = rt.intersection([
const RequiredAlertParamsRT = rt.type({
// NOTE: "count" would be better named as "threshold", but this would require a
// migration of encrypted saved objects, so we'll keep "count" until it's problematic.
count: ThresholdRT,
timeUnit: TimeUnitRT,
timeSize: timeSizeRT,
});

const OptionalAlertParamsRT = rt.partial({
groupBy: groupByRT,
});

export const alertParamsRT = rt.intersection([
rt.type({
count: DocumentCountRT,
criteria: criteriaRT,
timeUnit: TimeUnitRT,
timeSize: timeSizeRT,
criteria: countCriteriaRT,
...RequiredAlertParamsRT.props,
}),
rt.partial({
groupBy: groupByRT,
...OptionalAlertParamsRT.props,
}),
]);

export type LogDocumentCountAlertParams = rt.TypeOf<typeof LogDocumentCountAlertParamsRT>;
export type CountAlertParams = rt.TypeOf<typeof alertParamsRT>;

export const ratioAlertParamsRT = rt.intersection([
rt.type({
criteria: ratioCriteriaRT,
...RequiredAlertParamsRT.props,
}),
rt.partial({
...OptionalAlertParamsRT.props,
}),
]);

export type RatioAlertParams = rt.TypeOf<typeof ratioAlertParamsRT>;

export const AlertParamsRT = rt.union([alertParamsRT, ratioAlertParamsRT]);
export type AlertParams = rt.TypeOf<typeof AlertParamsRT>;

export const isRatioAlert = (criteria: AlertParams['criteria']): criteria is RatioCriteria => {
return criteria.length > 0 && Array.isArray(criteria[0]) ? true : false;
};

export const isRatioAlertParams = (params: AlertParams): params is RatioAlertParams => {
return isRatioAlert(params.criteria);
};

export const getNumerator = (criteria: RatioCriteria): Criteria => {
return criteria[0];
};

export const getDenominator = (criteria: RatioCriteria): Criteria => {
return criteria[1];
};

export const hasGroupBy = (alertParams: AlertParams) => {
const { groupBy } = alertParams;
return groupBy && groupBy.length > 0 ? true : false;
};

// Chart previews //
const chartPreviewHistogramBucket = rt.type({
key: rt.number,
doc_count: rt.number,
});

// ES query responses //
export const UngroupedSearchQueryResponseRT = rt.intersection([
commonSearchSuccessResponseFieldsRT,
rt.intersection([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
*/

import * as rt from 'io-ts';
import { criteriaRT, TimeUnitRT, timeSizeRT, groupByRT } from '../../alerting/logs/types';
import {
criteriaRT,
TimeUnitRT,
timeSizeRT,
groupByRT,
} from '../../alerting/logs/log_threshold/types';

export const LOG_ALERTS_CHART_PREVIEW_DATA_PATH = '/api/infra/log_alerts/chart_preview_data';

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import React, { useState, useCallback, useMemo } from 'react';
import { EuiPopover, EuiButtonEmpty, EuiContextMenuItem, EuiContextMenuPanel } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { AlertFlyout } from './alert_flyout';
import { useLinkProps } from '../../../hooks/use_link_props';
import { useLinkProps } from '../../../../hooks/use_link_props';

export const AlertDropdown = () => {
const [popoverOpen, setPopoverOpen] = useState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@

import React, { useContext } from 'react';
import { ApplicationStart, DocLinksStart, HttpStart, NotificationsStart } from 'src/core/public';

import { AlertsContextProvider, AlertAdd } from '../../../../../triggers_actions_ui/public';
import { TriggerActionsContext } from '../../../utils/triggers_actions_context';
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../../common/alerting/logs/types';
import { AlertsContextProvider, AlertAdd } from '../../../../../../triggers_actions_ui/public';
import { TriggerActionsContext } from '../../../../utils/triggers_actions_context';
import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public';
import { LOG_DOCUMENT_COUNT_ALERT_TYPE_ID } from '../../../../../common/alerting/logs/log_threshold/types';

interface Props {
visible?: boolean;
Expand Down
Loading

0 comments on commit f5d57d3

Please sign in to comment.