Skip to content

Commit

Permalink
[Logs UI] Log alerts chart previews (elastic#75296)
Browse files Browse the repository at this point in the history
* Add chart previews for log threshold alerts
  • Loading branch information
Kerry350 committed Aug 25, 2020
1 parent 1cae7b3 commit 405d480
Show file tree
Hide file tree
Showing 22 changed files with 1,017 additions and 112 deletions.
58 changes: 45 additions & 13 deletions x-pack/plugins/infra/common/alerting/logs/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,40 +96,64 @@ const DocumentCountRT = rt.type({

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

const CriterionRT = rt.type({
export const CriterionRT = rt.type({
field: rt.string,
comparator: ComparatorRT,
value: rt.union([rt.string, rt.number]),
});

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

const TimeUnitRT = rt.union([rt.literal('s'), rt.literal('m'), rt.literal('h'), rt.literal('d')]);
export const TimeUnitRT = rt.union([
rt.literal('s'),
rt.literal('m'),
rt.literal('h'),
rt.literal('d'),
]);
export type TimeUnit = rt.TypeOf<typeof TimeUnitRT>;

export const timeSizeRT = rt.number;
export const groupByRT = rt.array(rt.string);

export const LogDocumentCountAlertParamsRT = rt.intersection([
rt.type({
count: DocumentCountRT,
criteria: rt.array(CriterionRT),
criteria: criteriaRT,
timeUnit: TimeUnitRT,
timeSize: rt.number,
timeSize: timeSizeRT,
}),
rt.partial({
groupBy: rt.array(rt.string),
groupBy: groupByRT,
}),
]);

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

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

export const UngroupedSearchQueryResponseRT = rt.intersection([
commonSearchSuccessResponseFieldsRT,
rt.type({
hits: rt.type({
total: rt.type({
value: rt.number,
rt.intersection([
rt.type({
hits: rt.type({
total: rt.type({
value: rt.number,
}),
}),
}),
}),
// Chart preview buckets
rt.partial({
aggregations: rt.type({
histogramBuckets: rt.type({
buckets: rt.array(chartPreviewHistogramBucket),
}),
}),
}),
]),
]);

export type UngroupedSearchQueryResponse = rt.TypeOf<typeof UngroupedSearchQueryResponseRT>;
Expand All @@ -144,9 +168,17 @@ export const GroupedSearchQueryResponseRT = rt.intersection([
rt.type({
key: rt.record(rt.string, rt.string),
doc_count: rt.number,
filtered_results: rt.type({
doc_count: rt.number,
}),
filtered_results: rt.intersection([
rt.type({
doc_count: rt.number,
}),
// Chart preview buckets
rt.partial({
histogramBuckets: rt.type({
buckets: rt.array(chartPreviewHistogramBucket),
}),
}),
]),
})
),
}),
Expand Down
30 changes: 15 additions & 15 deletions x-pack/plugins/infra/common/color_palette.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { sampleColor, MetricsExplorerColor, colorTransformer } from './color_palette';
import { sampleColor, Color, colorTransformer } from './color_palette';
describe('Color Palette', () => {
describe('sampleColor()', () => {
it('should just work', () => {
const usedColors = [MetricsExplorerColor.color0];
const usedColors = [Color.color0];
const color = sampleColor(usedColors);
expect(color).toBe(MetricsExplorerColor.color1);
expect(color).toBe(Color.color1);
});

it('should return color0 when nothing is available', () => {
const usedColors = [
MetricsExplorerColor.color0,
MetricsExplorerColor.color1,
MetricsExplorerColor.color2,
MetricsExplorerColor.color3,
MetricsExplorerColor.color4,
MetricsExplorerColor.color5,
MetricsExplorerColor.color6,
MetricsExplorerColor.color7,
MetricsExplorerColor.color8,
MetricsExplorerColor.color9,
Color.color0,
Color.color1,
Color.color2,
Color.color3,
Color.color4,
Color.color5,
Color.color6,
Color.color7,
Color.color8,
Color.color9,
];
const color = sampleColor(usedColors);
expect(color).toBe(MetricsExplorerColor.color0);
expect(color).toBe(Color.color0);
});
});
describe('colorTransformer()', () => {
it('should just work', () => {
expect(colorTransformer(MetricsExplorerColor.color0)).toBe('#6092C0');
expect(colorTransformer(Color.color0)).toBe('#6092C0');
});
});
});
49 changes: 19 additions & 30 deletions x-pack/plugins/infra/common/color_palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { difference, first, values } from 'lodash';
import { euiPaletteColorBlind } from '@elastic/eui';

export enum MetricsExplorerColor {
export enum Color {
color0 = 'color0',
color1 = 'color1',
color2 = 'color2',
Expand All @@ -19,41 +19,30 @@ export enum MetricsExplorerColor {
color9 = 'color9',
}

export interface MetricsExplorerPalette {
[MetricsExplorerColor.color0]: string;
[MetricsExplorerColor.color1]: string;
[MetricsExplorerColor.color2]: string;
[MetricsExplorerColor.color3]: string;
[MetricsExplorerColor.color4]: string;
[MetricsExplorerColor.color5]: string;
[MetricsExplorerColor.color6]: string;
[MetricsExplorerColor.color7]: string;
[MetricsExplorerColor.color8]: string;
[MetricsExplorerColor.color9]: string;
}
export type Palette = {
[K in keyof typeof Color]: string;
};

const euiPalette = euiPaletteColorBlind();

export const defaultPalette: MetricsExplorerPalette = {
[MetricsExplorerColor.color0]: euiPalette[1], // (blue)
[MetricsExplorerColor.color1]: euiPalette[2], // (pink)
[MetricsExplorerColor.color2]: euiPalette[0], // (green-ish)
[MetricsExplorerColor.color3]: euiPalette[3], // (purple)
[MetricsExplorerColor.color4]: euiPalette[4], // (light pink)
[MetricsExplorerColor.color5]: euiPalette[5], // (yellow)
[MetricsExplorerColor.color6]: euiPalette[6], // (tan)
[MetricsExplorerColor.color7]: euiPalette[7], // (orange)
[MetricsExplorerColor.color8]: euiPalette[8], // (brown)
[MetricsExplorerColor.color9]: euiPalette[9], // (red)
export const defaultPalette: Palette = {
[Color.color0]: euiPalette[1], // (blue)
[Color.color1]: euiPalette[2], // (pink)
[Color.color2]: euiPalette[0], // (green-ish)
[Color.color3]: euiPalette[3], // (purple)
[Color.color4]: euiPalette[4], // (light pink)
[Color.color5]: euiPalette[5], // (yellow)
[Color.color6]: euiPalette[6], // (tan)
[Color.color7]: euiPalette[7], // (orange)
[Color.color8]: euiPalette[8], // (brown)
[Color.color9]: euiPalette[9], // (red)
};

export const createPaletteTransformer = (palette: MetricsExplorerPalette) => (
color: MetricsExplorerColor
) => palette[color];
export const createPaletteTransformer = (palette: Palette) => (color: Color) => palette[color];

export const colorTransformer = createPaletteTransformer(defaultPalette);

export const sampleColor = (usedColors: MetricsExplorerColor[] = []): MetricsExplorerColor => {
const available = difference(values(MetricsExplorerColor) as MetricsExplorerColor[], usedColors);
return first(available) || MetricsExplorerColor.color0;
export const sampleColor = (usedColors: Color[] = []): Color => {
const available = difference(values(Color) as Color[], usedColors);
return first(available) || Color.color0;
};
1 change: 1 addition & 0 deletions x-pack/plugins/infra/common/http_api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './metadata_api';
export * from './log_entries';
export * from './metrics_explorer';
export * from './metrics_api';
export * from './log_alerts';
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

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

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

const pointRT = rt.type({
timestamp: rt.number,
value: rt.number,
});

export type Point = rt.TypeOf<typeof pointRT>;

const serieRT = rt.type({
id: rt.string,
points: rt.array(pointRT),
});

const seriesRT = rt.array(serieRT);

export type Series = rt.TypeOf<typeof seriesRT>;

export const getLogAlertsChartPreviewDataSuccessResponsePayloadRT = rt.type({
data: rt.type({
series: seriesRT,
}),
});

export type GetLogAlertsChartPreviewDataSuccessResponsePayload = rt.TypeOf<
typeof getLogAlertsChartPreviewDataSuccessResponsePayloadRT
>;

export const getLogAlertsChartPreviewDataAlertParamsSubsetRT = rt.intersection([
rt.type({
criteria: criteriaRT,
timeUnit: TimeUnitRT,
timeSize: timeSizeRT,
}),
rt.partial({
groupBy: groupByRT,
}),
]);

export type GetLogAlertsChartPreviewDataAlertParamsSubset = rt.TypeOf<
typeof getLogAlertsChartPreviewDataAlertParamsSubsetRT
>;

export const getLogAlertsChartPreviewDataRequestPayloadRT = rt.type({
data: rt.type({
sourceId: rt.string,
alertParams: getLogAlertsChartPreviewDataAlertParamsSubsetRT,
buckets: rt.number,
}),
});

export type GetLogAlertsChartPreviewDataRequestPayload = rt.TypeOf<
typeof getLogAlertsChartPreviewDataRequestPayloadRT
>;
7 changes: 7 additions & 0 deletions x-pack/plugins/infra/common/http_api/log_alerts/index.ts
Original file line number Diff line number Diff line change
@@ -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;
* you may not use this file except in compliance with the Elastic License.
*/

export * from './chart_preview_data';
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
Comparator,
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
} from '../../../../server/lib/alerting/metric_threshold/types';
import { MetricsExplorerColor, colorTransformer } from '../../../../common/color_palette';
import { Color, colorTransformer } from '../../../../common/color_palette';
import { MetricsExplorerRow, MetricsExplorerAggregation } from '../../../../common/http_api';
import { MetricExplorerSeriesChart } from '../../../pages/metrics/metrics_explorer/components/series_chart';
import { MetricExpression, AlertContextMeta } from '../types';
Expand Down Expand Up @@ -80,7 +80,7 @@ export const ExpressionChart: React.FC<Props> = ({
const metric = {
field: expression.metric,
aggregation: expression.aggType as MetricsExplorerAggregation,
color: MetricsExplorerColor.color0,
color: Color.color0,
};
const isDarkMode = context.uiSettings?.get('theme:darkMode') || false;
const dateFormatter = useMemo(() => {
Expand Down Expand Up @@ -176,7 +176,7 @@ export const ExpressionChart: React.FC<Props> = ({
style={{
line: {
strokeWidth: 2,
stroke: colorTransformer(MetricsExplorerColor.color1),
stroke: colorTransformer(Color.color1),
opacity: 1,
},
}}
Expand All @@ -186,7 +186,7 @@ export const ExpressionChart: React.FC<Props> = ({
<RectAnnotation
id="lower-threshold"
style={{
fill: colorTransformer(MetricsExplorerColor.color1),
fill: colorTransformer(Color.color1),
opacity,
}}
dataValues={[
Expand All @@ -207,7 +207,7 @@ export const ExpressionChart: React.FC<Props> = ({
<RectAnnotation
id="lower-threshold"
style={{
fill: colorTransformer(MetricsExplorerColor.color1),
fill: colorTransformer(Color.color1),
opacity,
}}
dataValues={[
Expand All @@ -224,7 +224,7 @@ export const ExpressionChart: React.FC<Props> = ({
<RectAnnotation
id="upper-threshold"
style={{
fill: colorTransformer(MetricsExplorerColor.color1),
fill: colorTransformer(Color.color1),
opacity,
}}
dataValues={[
Expand All @@ -244,7 +244,7 @@ export const ExpressionChart: React.FC<Props> = ({
<RectAnnotation
id="upper-threshold"
style={{
fill: colorTransformer(MetricsExplorerColor.color1),
fill: colorTransformer(Color.color1),
opacity,
}}
dataValues={[
Expand All @@ -263,7 +263,7 @@ export const ExpressionChart: React.FC<Props> = ({
<RectAnnotation
id="upper-threshold"
style={{
fill: colorTransformer(MetricsExplorerColor.color1),
fill: colorTransformer(Color.color1),
opacity,
}}
dataValues={[
Expand Down
Loading

0 comments on commit 405d480

Please sign in to comment.