diff --git a/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.test.ts b/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.test.ts index c7143d19e1cc5..57487eb632fe3 100644 --- a/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.test.ts +++ b/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.test.ts @@ -7,7 +7,7 @@ import { random, mean } from 'lodash'; import { SanitizedAlert, AlertInstanceSummary } from '../types'; -import { IValidatedEvent } from '../../../event_log/server'; +import { IValidatedEvent, millisToNanos, nanosToMillis } from '../../../event_log/server'; import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER, LEGACY_EVENT_LOG_ACTIONS } from '../plugin'; import { alertInstanceSummaryFromEventLog } from './alert_instance_summary_from_event_log'; @@ -617,7 +617,7 @@ export class EventsFactory { event: { provider: EVENT_LOG_PROVIDER, action: EVENT_LOG_ACTIONS.execute, - duration: random(2000, 180000) * 1000 * 1000, + duration: millisToNanos(random(2000, 180000)), }, }; @@ -684,7 +684,7 @@ export class EventsFactory { return this.events .filter((ev) => ev?.event?.action === 'execute' && ev?.event?.duration !== undefined) .reduce((res: Record, ev) => { - res[ev?.['@timestamp']!] = ev?.event?.duration! / (1000 * 1000); + res[ev?.['@timestamp']!] = nanosToMillis(ev?.event?.duration!); return res; }, {}); } diff --git a/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.ts b/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.ts index 71023eb0b9361..53af2f6641f15 100644 --- a/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.ts +++ b/x-pack/plugins/alerting/server/lib/alert_instance_summary_from_event_log.ts @@ -7,11 +7,9 @@ import { mean } from 'lodash'; import { SanitizedAlert, AlertInstanceSummary, AlertInstanceStatus } from '../types'; -import { IEvent } from '../../../event_log/server'; +import { IEvent, nanosToMillis } from '../../../event_log/server'; import { EVENT_LOG_ACTIONS, EVENT_LOG_PROVIDER, LEGACY_EVENT_LOG_ACTIONS } from '../plugin'; -const Millis2Nanos = 1000 * 1000; - export interface AlertInstanceSummaryFromEventLogParams { alert: SanitizedAlert<{ bar: boolean }>; events: IEvent[]; @@ -75,7 +73,7 @@ export function alertInstanceSummaryFromEventLog( } if (event?.event?.duration) { - const eventDirationMillis = event?.event?.duration / Millis2Nanos; + const eventDirationMillis = nanosToMillis(event.event.duration); if (event?.['@timestamp']) { eventDurationsWithTimestamp[event?.['@timestamp']] = eventDirationMillis; } diff --git a/x-pack/plugins/alerting/server/lib/create_alert_event_log_record_object.ts b/x-pack/plugins/alerting/server/lib/create_alert_event_log_record_object.ts index 12300211cb0bb..933d8597680be 100644 --- a/x-pack/plugins/alerting/server/lib/create_alert_event_log_record_object.ts +++ b/x-pack/plugins/alerting/server/lib/create_alert_event_log_record_object.ts @@ -55,7 +55,7 @@ export function createAlertEventLogRecordObject(params: CreateAlertEventLogRecor category: [ruleType.producer], ...(state?.start ? { start: state.start as string } : {}), ...(state?.end ? { end: state.end as string } : {}), - ...(state?.duration !== undefined ? { duration: state.duration as number } : {}), + ...(state?.duration !== undefined ? { duration: state.duration as string } : {}), }, kibana: { ...(alerting ? alerting : {}), diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts index 613df958a34eb..78c966f7ecd6d 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.test.ts @@ -486,7 +486,7 @@ describe('Task Runner', () => { action: 'new-instance', category: ['alerts'], kind: 'alert', - duration: 0, + duration: '0', start: '1970-01-01T00:00:00.000Z', }, kibana: { @@ -519,7 +519,7 @@ describe('Task Runner', () => { event: { action: 'active-instance', category: ['alerts'], - duration: 0, + duration: '0', kind: 'alert', start: '1970-01-01T00:00:00.000Z', }, @@ -706,7 +706,7 @@ describe('Task Runner', () => { action: 'new-instance', category: ['alerts'], kind: 'alert', - duration: 0, + duration: '0', start: '1970-01-01T00:00:00.000Z', }, kibana: { @@ -739,7 +739,7 @@ describe('Task Runner', () => { action: 'active-instance', category: ['alerts'], kind: 'alert', - duration: 0, + duration: '0', start: '1970-01-01T00:00:00.000Z', }, kibana: { @@ -1041,7 +1041,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 86400000000000, + "duration": "86400000000000", "kind": "alert", "start": "1969-12-31T00:00:00.000Z", }, @@ -1379,7 +1379,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -1415,7 +1415,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -1606,7 +1606,7 @@ describe('Task Runner', () => { }, "state": Object { "bar": false, - "duration": 86400000000000, + "duration": "86400000000000", "start": "1969-12-31T00:00:00.000Z", }, }, @@ -1675,7 +1675,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 64800000000000, + "duration": "64800000000000", "end": "1970-01-01T00:00:00.000Z", "kind": "alert", "start": "1969-12-31T06:00:00.000Z", @@ -1711,7 +1711,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 86400000000000, + "duration": "86400000000000", "kind": "alert", "start": "1969-12-31T00:00:00.000Z", }, @@ -2189,7 +2189,7 @@ describe('Task Runner', () => { }, "state": Object { "bar": false, - "duration": 86400000000000, + "duration": "86400000000000", "start": "1969-12-31T00:00:00.000Z", }, }, @@ -2242,7 +2242,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 64800000000000, + "duration": "64800000000000", "end": "1970-01-01T00:00:00.000Z", "kind": "alert", "start": "1969-12-31T06:00:00.000Z", @@ -2279,7 +2279,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 86400000000000, + "duration": "86400000000000", "kind": "alert", "start": "1969-12-31T00:00:00.000Z", }, @@ -3327,7 +3327,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -3363,7 +3363,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -3399,7 +3399,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -3435,7 +3435,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 0, + "duration": "0", "kind": "alert", "start": "1970-01-01T00:00:00.000Z", }, @@ -3536,7 +3536,7 @@ describe('Task Runner', () => { state: { bar: false, start: '1969-12-31T00:00:00.000Z', - duration: 80000000000, + duration: '80000000000', }, }, '2': { @@ -3544,7 +3544,7 @@ describe('Task Runner', () => { state: { bar: false, start: '1969-12-31T06:00:00.000Z', - duration: 70000000000, + duration: '70000000000', }, }, }, @@ -3613,7 +3613,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 86400000000000, + "duration": "86400000000000", "kind": "alert", "start": "1969-12-31T00:00:00.000Z", }, @@ -3649,7 +3649,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 64800000000000, + "duration": "64800000000000", "kind": "alert", "start": "1969-12-31T06:00:00.000Z", }, @@ -3939,7 +3939,7 @@ describe('Task Runner', () => { state: { bar: false, start: '1969-12-31T00:00:00.000Z', - duration: 80000000000, + duration: '80000000000', }, }, '2': { @@ -3947,7 +3947,7 @@ describe('Task Runner', () => { state: { bar: false, start: '1969-12-31T06:00:00.000Z', - duration: 70000000000, + duration: '70000000000', }, }, }, @@ -4016,7 +4016,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 86400000000000, + "duration": "86400000000000", "end": "1970-01-01T00:00:00.000Z", "kind": "alert", "start": "1969-12-31T00:00:00.000Z", @@ -4052,7 +4052,7 @@ describe('Task Runner', () => { "category": Array [ "alerts", ], - "duration": 64800000000000, + "duration": "64800000000000", "end": "1970-01-01T00:00:00.000Z", "kind": "alert", "start": "1969-12-31T06:00:00.000Z", diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 61c9d2a537642..031ec85227eb4 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -37,7 +37,13 @@ import { import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type'; import { taskInstanceToAlertTaskInstance } from './alert_task_instance'; import { EVENT_LOG_ACTIONS } from '../plugin'; -import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_log/server'; +import { + IEvent, + IEventLogger, + SAVED_OBJECT_REL_PRIMARY, + millisToNanos, + nanosToMillis, +} from '../../../event_log/server'; import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error'; import { RulesClient } from '../rules_client'; import { partiallyUpdateAlert } from '../saved_objects'; @@ -594,7 +600,7 @@ export class TaskRunner< // Copy duration into execution status if available if (null != event.event?.duration) { - executionStatus.lastDuration = Math.round(event.event?.duration / Millis2Nanos); + executionStatus.lastDuration = nanosToMillis(event.event?.duration); } // if executionStatus indicates an error, fill in fields in @@ -695,9 +701,9 @@ function trackAlertDurations< const state = originalAlertIds.includes(id) ? originalAlerts[id].getState() : currentAlerts[id].getState(); - const duration = state.start - ? (new Date(currentTime).valueOf() - new Date(state.start as string).valueOf()) * 1000 * 1000 // nanoseconds - : undefined; + const durationInMs = + new Date(currentTime).valueOf() - new Date(state.start as string).valueOf(); + const duration = state.start ? millisToNanos(durationInMs) : undefined; currentAlerts[id].replaceState({ ...state, ...(state.start ? { start: state.start } : {}), @@ -708,9 +714,9 @@ function trackAlertDurations< // Inject end time into instance state of recovered instances for (const id of recoveredAlertIds) { const state = recoveredAlerts[id].getState(); - const duration = state.start - ? (new Date(currentTime).valueOf() - new Date(state.start as string).valueOf()) * 1000 * 1000 // nanoseconds - : undefined; + const durationInMs = + new Date(currentTime).valueOf() - new Date(state.start as string).valueOf(); + const duration = state.start ? millisToNanos(durationInMs) : undefined; recoveredAlerts[id].replaceState({ ...state, ...(duration ? { duration } : {}), @@ -835,7 +841,7 @@ function generateNewAndRecoveredInstanceEvents< category: [ruleType.producer], ...(state?.start ? { start: state.start as string } : {}), ...(state?.end ? { end: state.end as string } : {}), - ...(state?.duration !== undefined ? { duration: state.duration as number } : {}), + ...(state?.duration !== undefined ? { duration: state.duration as string } : {}), }, kibana: { alerting: { diff --git a/x-pack/plugins/event_log/common/index.ts b/x-pack/plugins/event_log/common/index.ts index 79ecd47628712..bed1a784a485c 100644 --- a/x-pack/plugins/event_log/common/index.ts +++ b/x-pack/plugins/event_log/common/index.ts @@ -6,3 +6,4 @@ */ export const BASE_EVENT_LOG_API_PATH = '/api/event_log'; +export { millisToNanos, nanosToMillis } from './lib'; diff --git a/x-pack/plugins/event_log/common/lib/index.ts b/x-pack/plugins/event_log/common/lib/index.ts new file mode 100644 index 0000000000000..40d3fb26189e6 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { millisToNanos } from './millis_to_nanos'; +export { nanosToMillis } from './nanos_to_millis'; diff --git a/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts b/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts new file mode 100644 index 0000000000000..4845d79305007 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/millis_to_nanos.test.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { millisToNanos } from './millis_to_nanos'; + +describe('millisToNanos', () => { + test('should return "0" when passing 0 millis', () => { + expect(millisToNanos(0)).toEqual('0'); + }); + + test('should return "1000000" when passing in 1 millis', () => { + expect(millisToNanos(1)).toEqual('1000000'); + }); + + test('should return "9007199254740991000000" when passing in 9007199254740991 (Number.MAX_SAFE_INTEGER)', () => { + expect(millisToNanos(9007199254740991)).toEqual('9007199254740991000000'); + }); + + test('should round to "1000000" wheen passing in 0.75 millis', () => { + expect(millisToNanos(0.75)).toEqual('1000000'); + }); +}); diff --git a/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts b/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts new file mode 100644 index 0000000000000..acb9e07f6c5a6 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/millis_to_nanos.ts @@ -0,0 +1,14 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function millisToNanos(millis: number): string { + const roundedMillis = Math.round(millis); + if (roundedMillis === 0) { + return '0'; + } + return `${roundedMillis}000000`; +} diff --git a/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts b/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts new file mode 100644 index 0000000000000..3a04c57b9edbf --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/nanos_to_millis.test.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { nanosToMillis } from './nanos_to_millis'; + +describe('nanosToMillis', () => { + test('should return 0 when passing in "0" nanos', () => { + expect(nanosToMillis('0')).toEqual(0); + }); + + test('should drop decimals when passing in "1" nanos', () => { + expect(nanosToMillis('1')).toEqual(0); + }); + + test('should drop decimals when passing in "1000001" nanos', () => { + expect(nanosToMillis('1000001')).toEqual(1); + }); + + test('should return 9007199254740991 (Number.MAX_SAFE_INTEGER) when passing in "9007199254740991000000" nanos', () => { + expect(nanosToMillis('9007199254740991000000')).toEqual(9007199254740991); + }); + + test('should work when numbers are passed in', () => { + expect(nanosToMillis(0)).toEqual(0); + expect(nanosToMillis(1)).toEqual(0); + expect(nanosToMillis(1000001)).toEqual(1); + }); +}); diff --git a/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts b/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts new file mode 100644 index 0000000000000..a0512fb528a91 --- /dev/null +++ b/x-pack/plugins/event_log/common/lib/nanos_to_millis.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +const ONE_MILLION = BigInt(1000 * 1000); + +export function nanosToMillis(nanos: string | number): number { + return Number(BigInt(nanos) / ONE_MILLION); +} diff --git a/x-pack/plugins/event_log/generated/schemas.ts b/x-pack/plugins/event_log/generated/schemas.ts index e73bafd9cb81e..f673fd51d6681 100644 --- a/x-pack/plugins/event_log/generated/schemas.ts +++ b/x-pack/plugins/event_log/generated/schemas.ts @@ -52,7 +52,7 @@ export const EventSchema = schema.maybe( code: ecsString(), created: ecsDate(), dataset: ecsString(), - duration: ecsNumber(), + duration: ecsStringOrNumber(), end: ecsDate(), hash: ecsString(), id: ecsString(), @@ -66,8 +66,8 @@ export const EventSchema = schema.maybe( reference: ecsString(), risk_score: ecsNumber(), risk_score_norm: ecsNumber(), - sequence: ecsNumber(), - severity: ecsNumber(), + sequence: ecsStringOrNumber(), + severity: ecsStringOrNumber(), start: ecsDate(), timezone: ecsString(), type: ecsStringMulti(), @@ -105,7 +105,7 @@ export const EventSchema = schema.maybe( task: schema.maybe( schema.object({ scheduled: ecsDate(), - schedule_delay: ecsNumber(), + schedule_delay: ecsStringOrNumber(), }) ), alerting: schema.maybe( @@ -124,12 +124,12 @@ export const EventSchema = schema.maybe( schema.object({ uuid: ecsString(), status: ecsString(), - status_order: ecsNumber(), + status_order: ecsStringOrNumber(), metrics: schema.maybe( schema.object({ - total_indexing_duration_ms: ecsNumber(), - total_search_duration_ms: ecsNumber(), - execution_gap_duration_s: ecsNumber(), + total_indexing_duration_ms: ecsStringOrNumber(), + total_search_duration_ms: ecsStringOrNumber(), + execution_gap_duration_s: ecsStringOrNumber(), }) ), }) @@ -168,6 +168,10 @@ function ecsNumber() { return schema.maybe(schema.number()); } +function ecsStringOrNumber() { + return schema.maybe(schema.oneOf([schema.string(), schema.number()])); +} + function ecsDate() { return schema.maybe(schema.string({ validate: validateDate })); } diff --git a/x-pack/plugins/event_log/scripts/create_schemas.js b/x-pack/plugins/event_log/scripts/create_schemas.js index c86722ccd76c6..1a775b44add8d 100755 --- a/x-pack/plugins/event_log/scripts/create_schemas.js +++ b/x-pack/plugins/event_log/scripts/create_schemas.js @@ -115,7 +115,8 @@ function writeEventLogConfigSchema(elSchema, ecsVersion) { } const StringTypes = new Set(['string', 'keyword', 'text', 'ip']); -const NumberTypes = new Set(['long', 'integer', 'float']); +const NumberTypes = new Set(['integer', 'float']); +const StringOrNumberTypes = new Set(['long']); function augmentMappings(mappings, multiValuedProperties) { for (const prop of multiValuedProperties) { @@ -145,6 +146,11 @@ function generateSchemaLines(lineWriter, prop, mappings) { return; } + if (StringOrNumberTypes.has(mappings.type)) { + lineWriter.addLine(`${propKey}: ecsStringOrNumber(),`); + return; + } + if (mappings.type === 'date') { lineWriter.addLine(`${propKey}: ecsDate(),`); return; @@ -310,6 +316,10 @@ function ecsNumber() { return schema.maybe(schema.number()); } +function ecsStringOrNumber() { + return schema.maybe(schema.oneOf([schema.string(), schema.number()])); +} + function ecsDate() { return schema.maybe(schema.string({ validate: validateDate })); } diff --git a/x-pack/plugins/event_log/server/event_log_client.test.ts b/x-pack/plugins/event_log/server/event_log_client.test.ts index c19bb4fb916a2..a315ed425c809 100644 --- a/x-pack/plugins/event_log/server/event_log_client.test.ts +++ b/x-pack/plugins/event_log/server/event_log_client.test.ts @@ -285,7 +285,7 @@ function fakeEvent(overrides = {}) { action: 'execute', start: '2020-03-30T14:55:47.054Z', end: '2020-03-30T14:55:47.055Z', - duration: 1000000, + duration: '1000000', }, kibana: { namespace: 'default', diff --git a/x-pack/plugins/event_log/server/event_logger.test.ts b/x-pack/plugins/event_log/server/event_logger.test.ts index d90fd93c60043..3ed3a96cd9bfe 100644 --- a/x-pack/plugins/event_log/server/event_logger.test.ts +++ b/x-pack/plugins/event_log/server/event_logger.test.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { nanosToMillis } from '../common'; import { IEvent, IEventLogger, IEventLogService } from './index'; import { ECS_VERSION } from './types'; import { EventLogService } from './event_log_service'; @@ -137,9 +138,9 @@ describe('EventLogger', () => { expect(timeStopValue).toBeGreaterThanOrEqual(timeStartValue); - const duration = event.event!.duration!; + const duration = Number(event.event!.duration!); expect(duration).toBeGreaterThan(0.95 * delayMS * 1000 * 1000); - expect(duration / (1000 * 1000)).toBeCloseTo(timeStopValue - timeStartValue); + expect(nanosToMillis(duration)).toBeCloseTo(timeStopValue - timeStartValue); }); test('timing method endTiming() method works when startTiming() is not called', async () => { diff --git a/x-pack/plugins/event_log/server/event_logger.ts b/x-pack/plugins/event_log/server/event_logger.ts index bcda73da215ae..015e78b71ae60 100644 --- a/x-pack/plugins/event_log/server/event_logger.ts +++ b/x-pack/plugins/event_log/server/event_logger.ts @@ -13,6 +13,7 @@ import { coerce } from 'semver'; import { Plugin } from './plugin'; import { EsContext } from './es'; import { EventLogService } from './event_log_service'; +import { millisToNanos } from '../common'; import { IEvent, IValidatedEvent, @@ -61,7 +62,7 @@ export class EventLogger implements IEventLogger { const end = Date.now(); event.event.end = new Date(end).toISOString(); - event.event.duration = (end - start) * 1000 * 1000; // nanoseconds + event.event.duration = millisToNanos(end - start); } // non-blocking, but spawns an async task to do the work diff --git a/x-pack/plugins/event_log/server/index.ts b/x-pack/plugins/event_log/server/index.ts index 6a04acf109a19..6b311c5b3992f 100644 --- a/x-pack/plugins/event_log/server/index.ts +++ b/x-pack/plugins/event_log/server/index.ts @@ -10,6 +10,8 @@ import { PluginInitializerContext, PluginConfigDescriptor } from 'src/core/serve import { ConfigSchema, IEventLogConfig } from './types'; import { Plugin } from './plugin'; +export { millisToNanos, nanosToMillis } from '../common'; + export type { IEventLogService, IEventLogger, diff --git a/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts b/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts index 3cd8e5eaae2ba..1fc714f4488e6 100644 --- a/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts +++ b/x-pack/plugins/event_log/server/routes/_mock_handler_arguments.ts @@ -50,7 +50,7 @@ export function fakeEvent(overrides = {}) { action: 'execute', start: '2020-03-30T14:55:47.054Z', end: '2020-03-30T14:55:47.055Z', - duration: 1000000, + duration: '1000000', }, kibana: { saved_objects: [ diff --git a/x-pack/plugins/event_log/tsconfig.json b/x-pack/plugins/event_log/tsconfig.json index e0e72fdbf6581..28dd8f244a3da 100644 --- a/x-pack/plugins/event_log/tsconfig.json +++ b/x-pack/plugins/event_log/tsconfig.json @@ -12,7 +12,7 @@ "generated/*", // have to declare *.json explicitly due to https://github.com/microsoft/TypeScript/issues/25636 "generated/*.json", - "common/*" + "common/**/*" ], "references": [ { "path": "../../../src/core/tsconfig.json" }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts index 9091b96ff335a..2c465dbdc8194 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts @@ -15,9 +15,7 @@ import { getEventLog, } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { IValidatedEvent } from '../../../../../plugins/event_log/server'; - -const NANOS_IN_MILLIS = 1000 * 1000; +import { IValidatedEvent, nanosToMillis } from '../../../../../plugins/event_log/server'; // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { @@ -536,14 +534,12 @@ export default function ({ getService }: FtrProviderContext) { const executeEventEnd = Date.parse(executeEvent?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(executeEventStart).to.be.ok(); expect(startExecuteEventStart).to.equal(executeEventStart); expect(executeEventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (executeEventEnd - executeEventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (executeEventEnd - executeEventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts index d1b88416208c9..77a15cc415134 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/alerting/alerts.ts @@ -21,15 +21,13 @@ import { TaskManagerUtils, getEventLog, } from '../../../common/lib'; -import { IValidatedEvent } from '../../../../../plugins/event_log/server'; +import { IValidatedEvent, nanosToMillis } from '../../../../../plugins/event_log/server'; import { TaskRunning, TaskRunningStage, } from '../../../../../plugins/task_manager/server/task_running'; import { ConcreteTaskInstance } from '../../../../../plugins/task_manager/server'; -const NANOS_IN_MILLIS = 1000 * 1000; - // eslint-disable-next-line import/no-default-export export default function alertTests({ getService }: FtrProviderContext) { const supertest = getService('supertest'); @@ -1285,13 +1283,11 @@ instanceStateValue: true const eventEnd = Date.parse(event?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(eventStart).to.be.ok(); expect(eventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (eventEnd - eventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (eventEnd - eventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index 10da2d852e806..dfaaac57a9a4f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -15,9 +15,7 @@ import { getEventLog, } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { IValidatedEvent } from '../../../../../plugins/event_log/server'; - -const NANOS_IN_MILLIS = 1000 * 1000; +import { IValidatedEvent, nanosToMillis } from '../../../../../plugins/event_log/server'; // eslint-disable-next-line import/no-default-export export default function ({ getService }: FtrProviderContext) { @@ -367,14 +365,12 @@ export default function ({ getService }: FtrProviderContext) { const executeEventEnd = Date.parse(executeEvent?.event?.end || 'undefined'); const dateNow = Date.now(); - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(executeEventStart).to.be.ok(); expect(startExecuteEventStart).to.equal(executeEventStart); expect(executeEventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (executeEventEnd - executeEventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (executeEventEnd - executeEventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts index 9bf7baf95d8d2..78ef48d794c44 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log.ts @@ -10,9 +10,7 @@ import uuid from 'uuid'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, getTestAlertData, ObjectRemover, getEventLog } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { IValidatedEvent } from '../../../../../plugins/event_log/server'; - -const NANOS_IN_MILLIS = 1000 * 1000; +import { IValidatedEvent, nanosToMillis } from '../../../../../plugins/event_log/server'; // eslint-disable-next-line import/no-default-export export default function eventLogTests({ getService }: FtrProviderContext) { @@ -591,15 +589,13 @@ export function validateEvent(event: IValidatedEvent, params: ValidateEventLogPa const dateNow = Date.now(); if (duration !== undefined) { - expect(typeof duration).to.be('number'); + expect(typeof duration).to.be('string'); expect(eventStart).to.be.ok(); if (shouldHaveEventEnd !== false) { expect(eventEnd).to.be.ok(); - const durationDiff = Math.abs( - Math.round(duration! / NANOS_IN_MILLIS) - (eventEnd - eventStart) - ); + const durationDiff = Math.abs(nanosToMillis(duration!) - (eventEnd - eventStart)); // account for rounding errors expect(durationDiff < 1).to.equal(true); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts index 2b92562b9bde5..67f5b35482dbe 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/event_log_alerts.ts @@ -9,7 +9,7 @@ import expect from '@kbn/expect'; import { Spaces } from '../../scenarios'; import { getUrlPrefix, getTestAlertData, ObjectRemover, getEventLog } from '../../../common/lib'; import { FtrProviderContext } from '../../../common/ftr_provider_context'; -import { IValidatedEvent } from '../../../../../plugins/event_log/server'; +import { IValidatedEvent, nanosToMillis } from '../../../../../plugins/event_log/server'; // eslint-disable-next-line import/no-default-export export default function eventLogAlertTests({ getService }: FtrProviderContext) { @@ -72,7 +72,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { const currentAlertSpan: { alertId?: string; start?: string; - durationToDate?: number; + durationToDate?: string; } = {}; for (let i = 0; i < instanceEvents.length; ++i) { switch (instanceEvents[i]?.event?.action) { @@ -83,7 +83,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { currentAlertSpan.alertId = instanceEvents[i]?.kibana?.alerting?.instance_id; currentAlertSpan.start = instanceEvents[i]?.event?.start; - currentAlertSpan.durationToDate = instanceEvents[i]?.event?.duration; + currentAlertSpan.durationToDate = `${instanceEvents[i]?.event?.duration}`; break; case 'active-instance': @@ -91,12 +91,13 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { expect(instanceEvents[i]?.event?.start).to.equal(currentAlertSpan.start); expect(instanceEvents[i]?.event?.end).to.be(undefined); - if (instanceEvents[i]?.event?.duration! !== 0) { - expect(instanceEvents[i]?.event?.duration! > currentAlertSpan.durationToDate!).to.be( - true - ); + if (instanceEvents[i]?.event?.duration! !== '0') { + expect( + BigInt(instanceEvents[i]?.event?.duration!) > + BigInt(currentAlertSpan.durationToDate!) + ).to.be(true); } - currentAlertSpan.durationToDate = instanceEvents[i]?.event?.duration; + currentAlertSpan.durationToDate = `${instanceEvents[i]?.event?.duration}`; break; case 'recovered-instance': @@ -106,7 +107,7 @@ export default function eventLogAlertTests({ getService }: FtrProviderContext) { expect( new Date(instanceEvents[i]?.event?.end!).valueOf() - new Date(instanceEvents[i]?.event?.start!).valueOf() - ).to.equal(instanceEvents[i]?.event?.duration! / 1000 / 1000); + ).to.equal(nanosToMillis(instanceEvents[i]?.event?.duration!)); break; } }