Skip to content

Commit

Permalink
feat(slo): introduce new search capabilities (#162665)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdelemme authored Aug 1, 2023
1 parent 1700e3e commit 757c881
Show file tree
Hide file tree
Showing 104 changed files with 7,385 additions and 1,409 deletions.
14 changes: 2 additions & 12 deletions x-pack/packages/kbn-slo-schema/src/models/duration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ describe('Duration', () => {
expect(new Duration(1, DurationUnit.Day).format()).toBe('1d');
expect(new Duration(1, DurationUnit.Week).format()).toBe('1w');
expect(new Duration(1, DurationUnit.Month).format()).toBe('1M');
expect(new Duration(1, DurationUnit.Quarter).format()).toBe('1Q');
expect(new Duration(1, DurationUnit.Year).format()).toBe('1Y');
});
});

Expand All @@ -39,31 +37,25 @@ describe('Duration', () => {
expect(short.isShorterThan(new Duration(1, DurationUnit.Day))).toBe(true);
expect(short.isShorterThan(new Duration(1, DurationUnit.Week))).toBe(true);
expect(short.isShorterThan(new Duration(1, DurationUnit.Month))).toBe(true);
expect(short.isShorterThan(new Duration(1, DurationUnit.Quarter))).toBe(true);
expect(short.isShorterThan(new Duration(1, DurationUnit.Year))).toBe(true);
});

it('returns false when the current duration is longer (or equal) than the other duration', () => {
const long = new Duration(1, DurationUnit.Year);
const long = new Duration(1, DurationUnit.Month);
expect(long.isShorterThan(new Duration(1, DurationUnit.Minute))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Hour))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Day))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Week))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Month))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Quarter))).toBe(false);
expect(long.isShorterThan(new Duration(1, DurationUnit.Year))).toBe(false);
});
});

describe('isLongerOrEqualThan', () => {
it('returns true when the current duration is longer or equal than the other duration', () => {
const long = new Duration(2, DurationUnit.Year);
const long = new Duration(2, DurationUnit.Month);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Hour))).toBe(true);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Day))).toBe(true);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Week))).toBe(true);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Month))).toBe(true);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Quarter))).toBe(true);
expect(long.isLongerOrEqualThan(new Duration(1, DurationUnit.Year))).toBe(true);
});

it('returns false when the current duration is shorter than the other duration', () => {
Expand All @@ -73,8 +65,6 @@ describe('Duration', () => {
expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Day))).toBe(false);
expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Week))).toBe(false);
expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Month))).toBe(false);
expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Quarter))).toBe(false);
expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Year))).toBe(false);
});
});

Expand Down
14 changes: 4 additions & 10 deletions x-pack/packages/kbn-slo-schema/src/models/duration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ enum DurationUnit {
'Day' = 'd',
'Week' = 'w',
'Month' = 'M',
'Quarter' = 'Q',
'Year' = 'Y',
}

class Duration {
Expand Down Expand Up @@ -55,6 +53,10 @@ class Duration {
format(): string {
return `${this.value}${this.unit}`;
}

asSeconds(): number {
return moment.duration(this.value, toMomentUnitOfTime(this.unit)).asSeconds();
}
}

const toDurationUnit = (unit: string): DurationUnit => {
Expand All @@ -69,10 +71,6 @@ const toDurationUnit = (unit: string): DurationUnit => {
return DurationUnit.Week;
case 'M':
return DurationUnit.Month;
case 'Q':
return DurationUnit.Quarter;
case 'y':
return DurationUnit.Year;
default:
throw new Error('invalid duration unit');
}
Expand All @@ -90,10 +88,6 @@ const toMomentUnitOfTime = (unit: DurationUnit): moment.unitOfTime.Diff => {
return 'weeks';
case DurationUnit.Month:
return 'months';
case DurationUnit.Quarter:
return 'quarters';
case DurationUnit.Year:
return 'years';
default:
assertNever(unit);
}
Expand Down
19 changes: 11 additions & 8 deletions x-pack/packages/kbn-slo-schema/src/rest_specs/slo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@

import * as t from 'io-ts';
import {
apmTransactionDurationIndicatorSchema,
apmTransactionErrorRateIndicatorSchema,
budgetingMethodSchema,
dateType,
durationType,
histogramIndicatorSchema,
historicalSummarySchema,
indicatorSchema,
indicatorTypesArraySchema,
indicatorTypesSchema,
kqlCustomIndicatorSchema,
metricCustomIndicatorSchema,
histogramIndicatorSchema,
objectiveSchema,
optionalSettingsSchema,
previewDataSchema,
Expand All @@ -24,9 +26,6 @@ import {
summarySchema,
tagsSchema,
timeWindowSchema,
apmTransactionErrorRateIndicatorSchema,
apmTransactionDurationIndicatorSchema,
durationType,
timeWindowTypeSchema,
} from '../schema';

Expand Down Expand Up @@ -69,12 +68,16 @@ const getSLOParamsSchema = t.type({
});

const sortDirectionSchema = t.union([t.literal('asc'), t.literal('desc')]);
const sortBySchema = t.union([t.literal('creationTime'), t.literal('indicatorType')]);
const sortBySchema = t.union([
t.literal('error_budget_consumed'),
t.literal('error_budget_remaining'),
t.literal('sli_value'),
t.literal('status'),
]);

const findSLOParamsSchema = t.partial({
query: t.partial({
name: t.string,
indicatorTypes: indicatorTypesArraySchema,
kqlQuery: t.string,
page: t.string,
perPage: t.string,
sortBy: sortBySchema,
Expand Down
4 changes: 0 additions & 4 deletions x-pack/packages/kbn-slo-schema/src/schema/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ const summarySchema = t.type({
errorBudget: errorBudgetSchema,
});

type SummarySchema = t.TypeOf<typeof summarySchema>;

const historicalSummarySchema = t.intersection([
t.type({
date: dateType,
Expand All @@ -59,8 +57,6 @@ const previewDataSchema = t.type({

const dateRangeSchema = t.type({ from: dateType, to: dateType });

export type { SummarySchema };

export {
ALL_VALUE,
allOrAnyString,
Expand Down
35 changes: 12 additions & 23 deletions x-pack/plugins/observability/docs/openapi/slo/bundled.json
Original file line number Diff line number Diff line change
Expand Up @@ -136,27 +136,13 @@
"$ref": "#/components/parameters/space_id"
},
{
"name": "name",
"name": "kqlQuery",
"in": "query",
"description": "Filter by name",
"description": "A valid kql query to filter the SLO with",
"schema": {
"type": "string"
},
"example": "awesome-service"
},
{
"name": "indicatorTypes",
"in": "query",
"description": "Filter by indicator type",
"schema": {
"type": "array",
"items": {
"type": "string"
}
},
"example": [
"sli.kql.custom"
]
"example": "slo.name:latency* and slo.tags : \"prod\""
},
{
"name": "page",
Expand All @@ -176,7 +162,7 @@
"type": "integer",
"default": 25
},
"example": 20
"example": 25
},
{
"name": "sortBy",
Expand All @@ -185,12 +171,14 @@
"schema": {
"type": "string",
"enum": [
"creationTime",
"indicatorType"
"sli_value",
"status",
"error_budget_consumed",
"error_budget_remaining"
],
"default": "creationTime"
"default": "status"
},
"example": "creationTime"
"example": "status"
},
{
"name": "sortDirection",
Expand Down Expand Up @@ -1333,7 +1321,8 @@
"sli.apm.transactionErrorRate": "#/components/schemas/indicator_properties_apm_availability",
"sli.kql.custom": "#/components/schemas/indicator_properties_custom_kql",
"sli.apm.transactionDuration": "#/components/schemas/indicator_properties_apm_latency",
"sli.apm.sli.metric.custom": "#/components/schemas/indicator_properties_custom_metric"
"sli.metric.custom": "#/components/schemas/indicator_properties_custom_metric",
"sli.histogram.custom": "#/components/schemas/indicator_properties_histogram"
}
},
"oneOf": [
Expand Down
30 changes: 12 additions & 18 deletions x-pack/plugins/observability/docs/openapi/slo/bundled.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,12 @@ paths:
parameters:
- $ref: '#/components/parameters/kbn_xsrf'
- $ref: '#/components/parameters/space_id'
- name: name
- name: kqlQuery
in: query
description: Filter by name
description: A valid kql query to filter the SLO with
schema:
type: string
example: awesome-service
- name: indicatorTypes
in: query
description: Filter by indicator type
schema:
type: array
items:
type: string
example:
- sli.kql.custom
example: 'slo.name:latency* and slo.tags : "prod"'
- name: page
in: query
description: The page number to return
Expand All @@ -108,17 +99,19 @@ paths:
schema:
type: integer
default: 25
example: 20
example: 25
- name: sortBy
in: query
description: Sort by field
schema:
type: string
enum:
- creationTime
- indicatorType
default: creationTime
example: creationTime
- sli_value
- status
- error_budget_consumed
- error_budget_remaining
default: status
example: status
- name: sortDirection
in: query
description: Sort order
Expand Down Expand Up @@ -920,7 +913,8 @@ components:
sli.apm.transactionErrorRate: '#/components/schemas/indicator_properties_apm_availability'
sli.kql.custom: '#/components/schemas/indicator_properties_custom_kql'
sli.apm.transactionDuration: '#/components/schemas/indicator_properties_apm_latency'
sli.apm.sli.metric.custom: '#/components/schemas/indicator_properties_custom_metric'
sli.metric.custom: '#/components/schemas/indicator_properties_custom_metric'
sli.histogram.custom: '#/components/schemas/indicator_properties_histogram'
oneOf:
- $ref: '#/components/schemas/indicator_properties_custom_kql'
- $ref: '#/components/schemas/indicator_properties_apm_availability'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,12 @@ get:
parameters:
- $ref: ../components/headers/kbn_xsrf.yaml
- $ref: ../components/parameters/space_id.yaml
- name: name
- name: kqlQuery
in: query
description: Filter by name
description: A valid kql query to filter the SLO with
schema:
type: string
example: awesome-service
- name: indicatorTypes
in: query
description: Filter by indicator type
schema:
type: array
items:
type: string
example: ['sli.kql.custom']
example: 'slo.name:latency* and slo.tags : "prod"'
- name: page
in: query
description: The page number to return
Expand All @@ -87,15 +79,15 @@ get:
schema:
type: integer
default: 25
example: 20
example: 25
- name: sortBy
in: query
description: Sort by field
schema:
type: string
enum: [creationTime, indicatorType]
default: creationTime
example: creationTime
enum: [sli_value, status, error_budget_consumed, error_budget_remaining]
default: status
example: status
- name: sortDirection
in: query
description: Sort order
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('SLO Selector', () => {
render(<SloSelector onSelected={onSelectedSpy} />);

expect(screen.getByTestId('sloSelector')).toBeTruthy();
expect(useFetchSloListMock).toHaveBeenCalledWith({ name: '' });
expect(useFetchSloListMock).toHaveBeenCalledWith({ kqlQuery: 'slo.name:*' });
});

it('searches SLOs when typing', async () => {
Expand All @@ -42,6 +42,6 @@ describe('SLO Selector', () => {
await wait(310); // debounce delay
});

expect(useFetchSloListMock).toHaveBeenCalledWith({ name: 'latency' });
expect(useFetchSloListMock).toHaveBeenCalledWith({ kqlQuery: 'slo.name:latency*' });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ function SloSelector({ initialSlo, onSelected, errors }: Props) {
const [options, setOptions] = useState<Array<EuiComboBoxOptionOption<string>>>([]);
const [selectedOptions, setSelectedOptions] = useState<Array<EuiComboBoxOptionOption<string>>>();
const [searchValue, setSearchValue] = useState<string>('');
const { isLoading, sloList } = useFetchSloList({ name: searchValue });
const { isLoading, sloList } = useFetchSloList({ kqlQuery: `slo.name:${searchValue}*` });
const hasError = errors !== undefined && errors.length > 0;

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import React from 'react';
import { EuiBadge, EuiFlexItem } from '@elastic/eui';
import { EuiBadge, EuiFlexItem, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { SLOWithSummaryResponse } from '@kbn/slo-schema';

Expand All @@ -19,11 +19,18 @@ export function SloStatusBadge({ slo }: SloStatusProps) {
<>
<EuiFlexItem grow={false}>
{slo.summary.status === 'NO_DATA' && (
<EuiBadge color="default">
{i18n.translate('xpack.observability.slo.sloStatusBadge.noData', {
defaultMessage: 'No data',
<EuiToolTip
position="top"
content={i18n.translate('xpack.observability.slo.sloStatusBadge.noDataTooltip', {
defaultMessage: 'It may take some time before the data is aggregated and available.',
})}
</EuiBadge>
>
<EuiBadge color="default">
{i18n.translate('xpack.observability.slo.sloStatusBadge.noData', {
defaultMessage: 'No data',
})}
</EuiBadge>
</EuiToolTip>
)}

{slo.summary.status === 'HEALTHY' && (
Expand Down
Loading

0 comments on commit 757c881

Please sign in to comment.