From fdcefb703d6aa366b040f24ee1a27eb14c7563c8 Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Tue, 29 Nov 2022 11:47:52 -0500 Subject: [PATCH] feat(slo): Add optional settings (#146470) --- x-pack/plugins/observability/dev_docs/slo.md | 5 +++ .../slo_transform_template.ts | 16 +++++++--- .../server/domain/models/duration.test.ts | 23 +++++++++++++ .../server/domain/models/duration.ts | 4 +++ .../domain/services/validate_slo.test.ts | 25 +++++++++++++++ .../server/domain/services/validate_slo.ts | 32 +++++++++++++++++++ .../observability/server/saved_objects/slo.ts | 7 ++++ .../server/services/slo/create_slo.ts | 7 +++- .../server/services/slo/find_slo.test.ts | 5 +++ .../server/services/slo/fixtures/slo.ts | 7 ++++ .../server/services/slo/get_slo.test.ts | 6 +++- .../server/services/slo/get_slo.ts | 1 + .../server/services/slo/sli_client.ts | 6 +++- .../apm_transaction_duration.test.ts.snap | 2 +- .../apm_transaction_error_rate.test.ts.snap | 2 +- .../__snapshots__/kql_custom.test.ts.snap | 2 +- .../apm_transaction_duration.ts | 3 +- .../apm_transaction_error_rate.ts | 3 +- .../slo/transform_generators/kql_custom.ts | 3 +- .../transform_generator.ts | 12 ++++++- .../server/services/slo/update_slo.test.ts | 19 +++++++++++ .../server/services/slo/update_slo.ts | 5 +++ .../server/types/rest_specs/slo.ts | 25 ++++++++++----- .../observability/server/types/schema/slo.ts | 11 +++++++ 24 files changed, 209 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/observability/dev_docs/slo.md b/x-pack/plugins/observability/dev_docs/slo.md index ba9d58f8c772f..bb64afcf748a5 100644 --- a/x-pack/plugins/observability/dev_docs/slo.md +++ b/x-pack/plugins/observability/dev_docs/slo.md @@ -38,7 +38,12 @@ For example, defining a **timeslices** budgeting method with a `95%` slice thres The target objective is the value the SLO needs to meet during the time window. If a **timeslices** budgeting method is used, we also need to define the **timeslice_target** which can be different than the overall SLO target. +### Optional settings +The default settings should be sufficient for most users, but if needed, the following properties can be overwritten: +- timestamp_field: The date time field to use from the source index +- sync_delay: The ingest delay in the source data +- frequency: How often do we query the source data ## Example diff --git a/x-pack/plugins/observability/server/assets/transform_templates/slo_transform_template.ts b/x-pack/plugins/observability/server/assets/transform_templates/slo_transform_template.ts index 6b313bdb76c5a..d9a8bfb1de8cb 100644 --- a/x-pack/plugins/observability/server/assets/transform_templates/slo_transform_template.ts +++ b/x-pack/plugins/observability/server/assets/transform_templates/slo_transform_template.ts @@ -10,26 +10,34 @@ import { TransformPivot, TransformPutTransformRequest, TransformSource, + TransformTimeSync, } from '@elastic/elasticsearch/lib/api/types'; +export interface TransformSettings { + frequency: TransformPutTransformRequest['frequency']; + sync_field: TransformTimeSync['field']; + sync_delay: TransformTimeSync['delay']; +} + export const getSLOTransformTemplate = ( transformId: string, source: TransformSource, destination: TransformDestination, groupBy: TransformPivot['group_by'] = {}, - aggregations: TransformPivot['aggregations'] = {} + aggregations: TransformPivot['aggregations'] = {}, + settings: TransformSettings ): TransformPutTransformRequest => ({ transform_id: transformId, source, - frequency: '1m', + frequency: settings.frequency, dest: destination, settings: { deduce_mappings: false, }, sync: { time: { - field: '@timestamp', - delay: '60s', + field: settings.sync_field, + delay: settings.sync_delay, }, }, pivot: { diff --git a/x-pack/plugins/observability/server/domain/models/duration.test.ts b/x-pack/plugins/observability/server/domain/models/duration.test.ts index 47c408766fea0..ce99d4be0571a 100644 --- a/x-pack/plugins/observability/server/domain/models/duration.test.ts +++ b/x-pack/plugins/observability/server/domain/models/duration.test.ts @@ -54,4 +54,27 @@ describe('Duration', () => { 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); + 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', () => { + const short = new Duration(1, DurationUnit.Minute); + expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Minute))).toBe(true); + expect(short.isLongerOrEqualThan(new Duration(1, DurationUnit.Hour))).toBe(false); + 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); + }); + }); }); diff --git a/x-pack/plugins/observability/server/domain/models/duration.ts b/x-pack/plugins/observability/server/domain/models/duration.ts index f80482f38a5be..8662330c67465 100644 --- a/x-pack/plugins/observability/server/domain/models/duration.ts +++ b/x-pack/plugins/observability/server/domain/models/duration.ts @@ -34,6 +34,10 @@ class Duration { return currentDurationMoment.asSeconds() < otherDurationMoment.asSeconds(); } + isLongerOrEqualThan(other: Duration): boolean { + return !this.isShorterThan(other); + } + format(): string { return `${this.value}${this.unit}`; } diff --git a/x-pack/plugins/observability/server/domain/services/validate_slo.test.ts b/x-pack/plugins/observability/server/domain/services/validate_slo.test.ts index 0be391acf984f..ba246e7b5837f 100644 --- a/x-pack/plugins/observability/server/domain/services/validate_slo.test.ts +++ b/x-pack/plugins/observability/server/domain/services/validate_slo.test.ts @@ -6,6 +6,7 @@ */ import { validateSLO } from '.'; +import { oneMinute, sixHours } from '../../services/slo/fixtures/duration'; import { createSLO } from '../../services/slo/fixtures/slo'; import { Duration, DurationUnit } from '../models/duration'; @@ -34,6 +35,30 @@ describe('validateSLO', () => { }); expect(() => validateSLO(slo)).toThrowError('Invalid time_window.duration'); }); + + describe('settings', () => { + it("throws when frequency is longer or equal than '1h'", () => { + const slo = createSLO({ + settings: { + frequency: sixHours(), + timestamp_field: '@timestamp', + sync_delay: oneMinute(), + }, + }); + expect(() => validateSLO(slo)).toThrowError('Invalid settings.frequency'); + }); + + it("throws when sync_delay is longer or equal than '6h'", () => { + const slo = createSLO({ + settings: { + frequency: oneMinute(), + timestamp_field: '@timestamp', + sync_delay: sixHours(), + }, + }); + expect(() => validateSLO(slo)).toThrowError('Invalid settings.sync_delay'); + }); + }); }); describe('slo with timeslices budgeting method', () => { diff --git a/x-pack/plugins/observability/server/domain/services/validate_slo.ts b/x-pack/plugins/observability/server/domain/services/validate_slo.ts index 8349ab1635290..e5994d7f09dab 100644 --- a/x-pack/plugins/observability/server/domain/services/validate_slo.ts +++ b/x-pack/plugins/observability/server/domain/services/validate_slo.ts @@ -41,6 +41,18 @@ export function validateSLO(slo: SLO) { throw new IllegalArgumentError('Invalid objective.timeslice_window'); } } + + validateSettings(slo); +} + +function validateSettings(slo: SLO) { + if (!isValidFrequencySettings(slo.settings.frequency)) { + throw new IllegalArgumentError('Invalid settings.frequency'); + } + + if (!isValidSyncDelaySettings(slo.settings.sync_delay)) { + throw new IllegalArgumentError('Invalid settings.sync_delay'); + } } function isValidTargetNumber(value: number): boolean { @@ -63,3 +75,23 @@ function isValidTimesliceWindowDuration(timesliceWindow: Duration, timeWindow: D timesliceWindow.isShorterThan(timeWindow) ); } + +/** + * validate that 1 minute <= frequency < 1 hour + */ +function isValidFrequencySettings(frequency: Duration): boolean { + return ( + frequency.isLongerOrEqualThan(new Duration(1, DurationUnit.Minute)) && + frequency.isShorterThan(new Duration(1, DurationUnit.Hour)) + ); +} + +/** + * validate that 1 minute <= sync_delay < 6 hour + */ +function isValidSyncDelaySettings(syncDelay: Duration): boolean { + return ( + syncDelay.isLongerOrEqualThan(new Duration(1, DurationUnit.Minute)) && + syncDelay.isShorterThan(new Duration(6, DurationUnit.Hour)) + ); +} diff --git a/x-pack/plugins/observability/server/saved_objects/slo.ts b/x-pack/plugins/observability/server/saved_objects/slo.ts index 5169c26252bc0..f63ef3881b9d5 100644 --- a/x-pack/plugins/observability/server/saved_objects/slo.ts +++ b/x-pack/plugins/observability/server/saved_objects/slo.ts @@ -46,6 +46,13 @@ export const slo: SavedObjectsType = { timeslice_window: { type: 'keyword' }, }, }, + settings: { + properties: { + timestamp_field: { type: 'keyword' }, + sync_delay: { type: 'keyword' }, + frequency: { type: 'keyword' }, + }, + }, revision: { type: 'short' }, created_at: { type: 'date' }, updated_at: { type: 'date' }, diff --git a/x-pack/plugins/observability/server/services/slo/create_slo.ts b/x-pack/plugins/observability/server/services/slo/create_slo.ts index aab2a42f7ede3..465eea0d04b71 100644 --- a/x-pack/plugins/observability/server/services/slo/create_slo.ts +++ b/x-pack/plugins/observability/server/services/slo/create_slo.ts @@ -7,7 +7,7 @@ import uuid from 'uuid'; -import { SLO } from '../../domain/models'; +import { Duration, DurationUnit, SLO } from '../../domain/models'; import { ResourceInstaller } from './resource_installer'; import { SLORepository } from './slo_repository'; import { TransformManager } from './transform_manager'; @@ -55,6 +55,11 @@ export class CreateSLO { return { ...params, id: uuid.v1(), + settings: { + timestamp_field: params.settings?.timestamp_field ?? '@timestamp', + sync_delay: params.settings?.sync_delay ?? new Duration(1, DurationUnit.Minute), + frequency: params.settings?.frequency ?? new Duration(1, DurationUnit.Minute), + }, revision: 1, created_at: now, updated_at: now, diff --git a/x-pack/plugins/observability/server/services/slo/find_slo.test.ts b/x-pack/plugins/observability/server/services/slo/find_slo.test.ts index 5de0afb3aa3d7..1ac802183c22a 100644 --- a/x-pack/plugins/observability/server/services/slo/find_slo.test.ts +++ b/x-pack/plugins/observability/server/services/slo/find_slo.test.ts @@ -64,6 +64,11 @@ describe('FindSLO', () => { duration: '7d', is_rolling: true, }, + settings: { + timestamp_field: '@timestamp', + sync_delay: '1m', + frequency: '1m', + }, summary: { sli_value: 0.9999, error_budget: { diff --git a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts index 2d0b24b77959a..37c93e8cdfc0e 100644 --- a/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts +++ b/x-pack/plugins/observability/server/services/slo/fixtures/slo.ts @@ -14,6 +14,8 @@ import { sloSchema } from '../../../types/schema'; import { APMTransactionDurationIndicator, APMTransactionErrorRateIndicator, + Duration, + DurationUnit, Indicator, KQLCustomIndicator, SLO, @@ -74,6 +76,11 @@ const defaultSLO: Omit = { target: 0.999, }, indicator: createAPMTransactionDurationIndicator(), + settings: { + timestamp_field: '@timestamp', + sync_delay: new Duration(1, DurationUnit.Minute), + frequency: new Duration(1, DurationUnit.Minute), + }, }; export const createSLOParams = (params: Partial = {}): CreateSLOParams => ({ diff --git a/x-pack/plugins/observability/server/services/slo/get_slo.test.ts b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts index 49730de0e7424..906edb75664a7 100644 --- a/x-pack/plugins/observability/server/services/slo/get_slo.test.ts +++ b/x-pack/plugins/observability/server/services/slo/get_slo.test.ts @@ -60,7 +60,11 @@ describe('GetSLO', () => { duration: '7d', is_rolling: true, }, - + settings: { + timestamp_field: '@timestamp', + sync_delay: '1m', + frequency: '1m', + }, summary: { sli_value: 0.9999, error_budget: { diff --git a/x-pack/plugins/observability/server/services/slo/get_slo.ts b/x-pack/plugins/observability/server/services/slo/get_slo.ts index 802ba5499ed86..62b2e7b9cd876 100644 --- a/x-pack/plugins/observability/server/services/slo/get_slo.ts +++ b/x-pack/plugins/observability/server/services/slo/get_slo.ts @@ -32,6 +32,7 @@ export class GetSLO { time_window: slo.time_window, budgeting_method: slo.budgeting_method, objective: slo.objective, + settings: slo.settings, summary: slo.summary, revision: slo.revision, created_at: slo.created_at, diff --git a/x-pack/plugins/observability/server/services/slo/sli_client.ts b/x-pack/plugins/observability/server/services/slo/sli_client.ts index a62ba6c6817c6..11294b1b82229 100644 --- a/x-pack/plugins/observability/server/services/slo/sli_client.ts +++ b/x-pack/plugins/observability/server/services/slo/sli_client.ts @@ -55,11 +55,15 @@ export class DefaultSLIClient implements SLIClient { generateSearchQuery(slo, dateRangeBySlo[slo.id]), ]); + const indicatorDataBySlo: Record = {}; + if (searches.length === 0) { + return indicatorDataBySlo; + } + const result = await this.esClient.msearch>({ searches, }); - const indicatorDataBySlo: Record = {}; for (let i = 0; i < result.responses.length; i++) { const slo = sloList[i]; if ('error' in result.responses[i]) { diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap index 187126b8e8efd..e62dab5e112e2 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_duration.test.ts.snap @@ -177,7 +177,7 @@ Object { }, "sync": Object { "time": Object { - "delay": "60s", + "delay": "1m", "field": "@timestamp", }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap index 3a7826cb9d8b5..0d41f6a45fb8a 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/apm_transaction_error_rate.test.ts.snap @@ -182,7 +182,7 @@ Object { }, "sync": Object { "time": Object { - "delay": "60s", + "delay": "1m", "field": "@timestamp", }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap index 5fed8a8e08977..1aa05dfb2cf3b 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/__snapshots__/kql_custom.test.ts.snap @@ -242,7 +242,7 @@ Object { }, "sync": Object { "time": Object { - "delay": "60s", + "delay": "1m", "field": "@timestamp", }, }, diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts index 2725c33af3940..6cba9c32d40ac 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_duration.ts @@ -30,7 +30,8 @@ export class ApmTransactionDurationTransformGenerator extends TransformGenerator this.buildSource(slo, slo.indicator), this.buildDestination(), this.buildCommonGroupBy(slo), - this.buildAggregations(slo.indicator) + this.buildAggregations(slo.indicator), + this.buildSettings(slo) ); } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts index b0418d5f1f9f3..a68eb490ebde1 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/apm_transaction_error_rate.ts @@ -32,7 +32,8 @@ export class ApmTransactionErrorRateTransformGenerator extends TransformGenerato this.buildSource(slo, slo.indicator), this.buildDestination(), this.buildCommonGroupBy(slo), - this.buildAggregations(slo, slo.indicator) + this.buildAggregations(slo, slo.indicator), + this.buildSettings(slo) ); } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts index 02809a0d05659..f5497118ef611 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/kql_custom.ts @@ -30,7 +30,8 @@ export class KQLCustomTransformGenerator extends TransformGenerator { this.buildSource(slo, slo.indicator), this.buildDestination(), this.buildCommonGroupBy(slo), - this.buildAggregations(slo, slo.indicator) + this.buildAggregations(slo, slo.indicator), + this.buildSettings(slo) ); } diff --git a/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts b/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts index 69a80fa9a0f4e..2903d2791d6b7 100644 --- a/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts +++ b/x-pack/plugins/observability/server/services/slo/transform_generators/transform_generator.ts @@ -10,6 +10,7 @@ import { AggregationsCalendarInterval, TransformPutTransformRequest, } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { TransformSettings } from '../../../assets/transform_templates/slo_transform_template'; import { calendarAlignedTimeWindowSchema, rollingTimeWindowSchema, @@ -140,12 +141,21 @@ export abstract class TransformGenerator { }, }, }), + // Field used in the destination index, using @timestamp as per mapping definition '@timestamp': { date_histogram: { - field: '@timestamp', + field: slo.settings.timestamp_field, calendar_interval: '1m' as AggregationsCalendarInterval, }, }, }; } + + public buildSettings(slo: SLO): TransformSettings { + return { + frequency: slo.settings.frequency.format(), + sync_field: slo.settings.timestamp_field, + sync_delay: slo.settings.sync_delay.format(), + }; + } } diff --git a/x-pack/plugins/observability/server/services/slo/update_slo.test.ts b/x-pack/plugins/observability/server/services/slo/update_slo.test.ts index cd3dbb6352936..db0e726c83066 100644 --- a/x-pack/plugins/observability/server/services/slo/update_slo.test.ts +++ b/x-pack/plugins/observability/server/services/slo/update_slo.test.ts @@ -47,6 +47,25 @@ describe('UpdateSLO', () => { }); describe('with breaking changes', () => { + it('consideres settings as a breaking change', async () => { + const slo = createSLO(); + mockRepository.findById.mockResolvedValueOnce(slo); + + const newSettings = { ...slo.settings, timestamp_field: 'newField' }; + await updateSLO.execute(slo.id, { settings: newSettings }); + + expectDeletionOfObsoleteSLOData(slo); + expect(mockRepository.save).toBeCalledWith( + expect.objectContaining({ + ...slo, + settings: newSettings, + revision: 2, + updated_at: expect.anything(), + }) + ); + expectInstallationOfNewSLOTransform(); + }); + it('removes the obsolete data from the SLO previous revision', async () => { const slo = createSLO({ indicator: createAPMTransactionErrorRateIndicator({ environment: 'development' }), diff --git a/x-pack/plugins/observability/server/services/slo/update_slo.ts b/x-pack/plugins/observability/server/services/slo/update_slo.ts index 8712119d345de..0a496a177b213 100644 --- a/x-pack/plugins/observability/server/services/slo/update_slo.ts +++ b/x-pack/plugins/observability/server/services/slo/update_slo.ts @@ -52,6 +52,10 @@ export class UpdateSLO { hasBreakingChange = true; } + if (!deepEqual(originalSlo.settings, updatedSlo.settings)) { + hasBreakingChange = true; + } + if (hasBreakingChange) { updatedSlo.revision++; } @@ -87,6 +91,7 @@ export class UpdateSLO { budgeting_method: slo.budgeting_method, time_window: slo.time_window, objective: slo.objective, + settings: slo.settings, created_at: slo.created_at, updated_at: slo.updated_at, }); diff --git a/x-pack/plugins/observability/server/types/rest_specs/slo.ts b/x-pack/plugins/observability/server/types/rest_specs/slo.ts index 2dd83528b2573..40253ad998b12 100644 --- a/x-pack/plugins/observability/server/types/rest_specs/slo.ts +++ b/x-pack/plugins/observability/server/types/rest_specs/slo.ts @@ -12,19 +12,24 @@ import { dateType, indicatorSchema, objectiveSchema, + optionalSettingsSchema, + settingsSchema, summarySchema, timeWindowSchema, } from '../schema'; const createSLOParamsSchema = t.type({ - body: t.type({ - name: t.string, - description: t.string, - indicator: indicatorSchema, - time_window: timeWindowSchema, - budgeting_method: budgetingMethodSchema, - objective: objectiveSchema, - }), + body: t.intersection([ + t.type({ + name: t.string, + description: t.string, + indicator: indicatorSchema, + time_window: timeWindowSchema, + budgeting_method: budgetingMethodSchema, + objective: objectiveSchema, + }), + t.partial({ settings: optionalSettingsSchema }), + ]), }); const createSLOResponseSchema = t.type({ @@ -59,6 +64,7 @@ const getSLOResponseSchema = t.type({ time_window: timeWindowSchema, budgeting_method: budgetingMethodSchema, objective: objectiveSchema, + settings: settingsSchema, summary: summarySchema, revision: t.number, created_at: dateType, @@ -76,6 +82,7 @@ const updateSLOParamsSchema = t.type({ time_window: timeWindowSchema, budgeting_method: budgetingMethodSchema, objective: objectiveSchema, + settings: settingsSchema, }), }); @@ -87,6 +94,7 @@ const updateSLOResponseSchema = t.type({ time_window: timeWindowSchema, budgeting_method: budgetingMethodSchema, objective: objectiveSchema, + settings: settingsSchema, created_at: dateType, updated_at: dateType, }); @@ -105,6 +113,7 @@ const findSLOResponseSchema = t.type({ budgeting_method: budgetingMethodSchema, objective: objectiveSchema, summary: summarySchema, + settings: settingsSchema, revision: t.number, created_at: dateType, updated_at: dateType, diff --git a/x-pack/plugins/observability/server/types/schema/slo.ts b/x-pack/plugins/observability/server/types/schema/slo.ts index a2e2145af5e8c..99aa630303868 100644 --- a/x-pack/plugins/observability/server/types/schema/slo.ts +++ b/x-pack/plugins/observability/server/types/schema/slo.ts @@ -24,6 +24,14 @@ const objectiveSchema = t.intersection([ t.partial({ timeslice_target: t.number, timeslice_window: durationType }), ]); +const settingsSchema = t.type({ + timestamp_field: t.string, + sync_delay: durationType, + frequency: durationType, +}); + +const optionalSettingsSchema = t.partial({ ...settingsSchema.props }); + const sloSchema = t.type({ id: t.string, name: t.string, @@ -32,6 +40,7 @@ const sloSchema = t.type({ time_window: timeWindowSchema, budgeting_method: budgetingMethodSchema, objective: objectiveSchema, + settings: settingsSchema, revision: t.number, created_at: dateType, updated_at: dateType, @@ -43,6 +52,8 @@ export { budgetingMethodSchema, objectiveSchema, occurrencesBudgetingMethodSchema, + optionalSettingsSchema, + settingsSchema, sloSchema, sloWithSummarySchema, timeslicesBudgetingMethodSchema,