Skip to content

Commit

Permalink
[SLO] Add timeslice metric indicator (elastic#168539)
Browse files Browse the repository at this point in the history
## Summary

This PR adds the new Timeslice Metric indicator for SLOs. Due to the
nature of these statistical aggregations, this indicator requires the
budgeting method to be set to `timeslices`; we ignore the timeslice
threshold in favor of the threshold set in the metric definition.

Users can create SLOs based on the following aggregations:
- Average
- Min
- Max
- Sum
- Cardinality
- Percentile
- Document count
- Std. Deviation
- Last Value

Other notable feature include:

- The ability to define an equation which supports basic math and logic
- Users can define a threshold based on the equation for good slices vs
bad slices

<img width="800" alt="image"
src="https://github.com/elastic/kibana/assets/41702/05af1ced-40cd-4a05-9dfc-e83ea7bfb5ab">

### Counter Metric Example

<img width="800" alt="image"
src="https://github.com/elastic/kibana/assets/41702/05eb5a0f-3043-493d-8add-df0d3bf8de02">


CC: @lucasmoore

---------

Co-authored-by: Kevin Delemme <kdelemme@gmail.com>
  • Loading branch information
simianhacker and kdelemme authored Oct 17, 2023
1 parent 2932b77 commit befbe10
Show file tree
Hide file tree
Showing 38 changed files with 3,225 additions and 29 deletions.
12 changes: 12 additions & 0 deletions x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
indicatorTypesSchema,
kqlCustomIndicatorSchema,
metricCustomIndicatorSchema,
timesliceMetricIndicatorSchema,
objectiveSchema,
optionalSettingsSchema,
previewDataSchema,
Expand All @@ -28,6 +29,9 @@ import {
tagsSchema,
timeWindowSchema,
timeWindowTypeSchema,
timesliceMetricBasicMetricWithField,
timesliceMetricDocCountMetric,
timesliceMetricPercentileMetric,
} from '../schema';

const createSLOParamsSchema = t.type({
Expand Down Expand Up @@ -270,6 +274,10 @@ type Indicator = t.OutputOf<typeof indicatorSchema>;
type APMTransactionErrorRateIndicator = t.OutputOf<typeof apmTransactionErrorRateIndicatorSchema>;
type APMTransactionDurationIndicator = t.OutputOf<typeof apmTransactionDurationIndicatorSchema>;
type MetricCustomIndicator = t.OutputOf<typeof metricCustomIndicatorSchema>;
type TimesliceMetricIndicator = t.OutputOf<typeof timesliceMetricIndicatorSchema>;
type TimesliceMetricBasicMetricWithField = t.OutputOf<typeof timesliceMetricBasicMetricWithField>;
type TimesliceMetricDocCountMetric = t.OutputOf<typeof timesliceMetricDocCountMetric>;
type TimesclieMetricPercentileMetric = t.OutputOf<typeof timesliceMetricPercentileMetric>;
type HistogramIndicator = t.OutputOf<typeof histogramIndicatorSchema>;
type KQLCustomIndicator = t.OutputOf<typeof kqlCustomIndicatorSchema>;

Expand Down Expand Up @@ -327,6 +335,10 @@ export type {
IndicatorType,
Indicator,
MetricCustomIndicator,
TimesliceMetricIndicator,
TimesliceMetricBasicMetricWithField,
TimesclieMetricPercentileMetric,
TimesliceMetricDocCountMetric,
HistogramIndicator,
KQLCustomIndicator,
TimeWindow,
Expand Down
88 changes: 87 additions & 1 deletion x-pack/packages/kbn-slo-schema/src/schema/indicators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,83 @@ const kqlCustomIndicatorSchema = t.type({
]),
});

const timesliceMetricComparatorMapping = {
GT: '>',
GTE: '>=',
LT: '<',
LTE: '<=',
};

const timesliceMetricComparator = t.keyof(timesliceMetricComparatorMapping);

const timesliceMetricBasicMetricWithField = t.intersection([
t.type({
name: t.string,
aggregation: t.keyof({
avg: true,
max: true,
min: true,
sum: true,
cardinality: true,
last_value: true,
std_deviation: true,
}),
field: t.string,
}),
t.partial({
filter: t.string,
}),
]);

const timesliceMetricDocCountMetric = t.intersection([
t.type({
name: t.string,
aggregation: t.literal('doc_count'),
}),
t.partial({
filter: t.string,
}),
]);

const timesliceMetricPercentileMetric = t.intersection([
t.type({
name: t.string,
aggregation: t.literal('percentile'),
field: t.string,
percentile: t.number,
}),
t.partial({
filter: t.string,
}),
]);

const timesliceMetricMetricDef = t.union([
timesliceMetricBasicMetricWithField,
timesliceMetricDocCountMetric,
timesliceMetricPercentileMetric,
]);

const timesliceMetricDef = t.type({
metrics: t.array(timesliceMetricMetricDef),
equation: t.string,
threshold: t.number,
comparator: timesliceMetricComparator,
});
const timesliceMetricIndicatorTypeSchema = t.literal('sli.metric.timeslice');
const timesliceMetricIndicatorSchema = t.type({
type: timesliceMetricIndicatorTypeSchema,
params: t.intersection([
t.type({
index: t.string,
metric: timesliceMetricDef,
timestampField: t.string,
}),
t.partial({
filter: t.string,
}),
]),
});

const metricCustomValidAggregations = t.keyof({
sum: true,
});
Expand Down Expand Up @@ -149,6 +226,7 @@ const indicatorTypesSchema = t.union([
apmTransactionErrorRateIndicatorTypeSchema,
kqlCustomIndicatorTypeSchema,
metricCustomIndicatorTypeSchema,
timesliceMetricIndicatorTypeSchema,
histogramIndicatorTypeSchema,
]);

Expand Down Expand Up @@ -176,6 +254,7 @@ const indicatorSchema = t.union([
apmTransactionErrorRateIndicatorSchema,
kqlCustomIndicatorSchema,
metricCustomIndicatorSchema,
timesliceMetricIndicatorSchema,
histogramIndicatorSchema,
]);

Expand All @@ -186,8 +265,15 @@ export {
apmTransactionErrorRateIndicatorTypeSchema,
kqlCustomIndicatorSchema,
kqlCustomIndicatorTypeSchema,
metricCustomIndicatorTypeSchema,
metricCustomIndicatorSchema,
metricCustomIndicatorTypeSchema,
timesliceMetricComparatorMapping,
timesliceMetricIndicatorSchema,
timesliceMetricIndicatorTypeSchema,
timesliceMetricMetricDef,
timesliceMetricBasicMetricWithField,
timesliceMetricDocCountMetric,
timesliceMetricPercentileMetric,
histogramIndicatorTypeSchema,
histogramIndicatorSchema,
indicatorSchema,
Expand Down
Loading

0 comments on commit befbe10

Please sign in to comment.