diff --git a/x-pack/plugins/event_log/generated/mappings.json b/x-pack/plugins/event_log/generated/mappings.json index 5e6a9d660f82a..e9f030ffbc886 100644 --- a/x-pack/plugins/event_log/generated/mappings.json +++ b/x-pack/plugins/event_log/generated/mappings.json @@ -309,19 +309,6 @@ } } }, - "reporting": { - "properties": { - "id": { - "type": "keyword" - }, - "jobType": { - "type": "keyword" - }, - "byteSize": { - "type": "long" - } - } - }, "saved_objects": { "type": "nested", "properties": { diff --git a/x-pack/plugins/event_log/generated/schemas.ts b/x-pack/plugins/event_log/generated/schemas.ts index 4607495b85c4e..d61689d6238e4 100644 --- a/x-pack/plugins/event_log/generated/schemas.ts +++ b/x-pack/plugins/event_log/generated/schemas.ts @@ -140,13 +140,6 @@ export const EventSchema = schema.maybe( ), }) ), - reporting: schema.maybe( - schema.object({ - id: ecsString(), - jobType: ecsString(), - byteSize: ecsNumber(), - }) - ), saved_objects: schema.maybe( schema.arrayOf( schema.object({ diff --git a/x-pack/plugins/event_log/scripts/mappings.js b/x-pack/plugins/event_log/scripts/mappings.js index 22d36d7f20d4c..091b50eceea6c 100644 --- a/x-pack/plugins/event_log/scripts/mappings.js +++ b/x-pack/plugins/event_log/scripts/mappings.js @@ -91,20 +91,6 @@ exports.EcsCustomPropertyMappings = { }, }, }, - // reporting specific fields - reporting: { - properties: { - id: { - type: 'keyword', - }, - jobType: { - type: 'keyword', - }, - byteSize: { - type: 'long', - }, - }, - }, // array of saved object references, for "linking" via search saved_objects: { type: 'nested', diff --git a/x-pack/plugins/reporting/kibana.json b/x-pack/plugins/reporting/kibana.json index e7162d0974de6..8f75a462ed8f6 100644 --- a/x-pack/plugins/reporting/kibana.json +++ b/x-pack/plugins/reporting/kibana.json @@ -18,7 +18,6 @@ "licensing", "uiActions", "taskManager", - "eventLog", "embeddable", "screenshotting", "screenshotMode", diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index 5c00089afc381..745542c358a69 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -21,7 +21,6 @@ import type { import type { PluginStart as DataPluginStart } from 'src/plugins/data/server'; import type { FieldFormatsStart } from 'src/plugins/field_formats/server'; import { KibanaRequest, ServiceStatusLevels } from '../../../../src/core/server'; -import type { IEventLogService } from '../../event_log/server'; import type { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import type { LicensingPluginStart } from '../../licensing/server'; import type { ScreenshotResult, ScreenshottingStart } from '../../screenshotting/server'; @@ -40,7 +39,6 @@ import { ExecuteReportTask, MonitorReportsTask, ReportTaskParams } from './lib/t import type { ReportingPluginRouter, ScreenshotOptions } from './types'; export interface ReportingInternalSetup { - eventLog: IEventLogService; basePath: Pick; router: ReportingPluginRouter; features: FeaturesPluginSetup; @@ -390,7 +388,7 @@ export class ReportingCore { } public getEventLogger(report: IReport, task?: { id: string }) { - const ReportingEventLogger = reportingEventLoggerFactory(this.pluginSetupDeps!.eventLog); + const ReportingEventLogger = reportingEventLoggerFactory(this.logger); return new ReportingEventLogger(report, task); } } diff --git a/x-pack/plugins/reporting/server/lib/event_logger/adapter.test.ts b/x-pack/plugins/reporting/server/lib/event_logger/adapter.test.ts new file mode 100644 index 0000000000000..aef569a49e357 --- /dev/null +++ b/x-pack/plugins/reporting/server/lib/event_logger/adapter.test.ts @@ -0,0 +1,67 @@ +/* + * 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 { LogMeta } from 'kibana/server'; +import { createMockLevelLogger } from '../../test_helpers'; +import { EcsLogAdapter } from './adapter'; + +describe('EcsLogAdapter', () => { + const logger = createMockLevelLogger(); + beforeAll(() => { + jest + .spyOn(global.Date, 'now') + .mockImplementationOnce(() => new Date('2021-04-12T16:00:00.000Z').valueOf()) + .mockImplementationOnce(() => new Date('2021-04-12T16:02:00.000Z').valueOf()); + }); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('captures a log event', () => { + const eventLogger = new EcsLogAdapter(logger, { event: { provider: 'test-adapting' } }); + + const event = { kibana: { reporting: { wins: 5000 } } } as object & LogMeta; // an object that extends LogMeta + eventLogger.logEvent('hello world', event); + + expect(logger.debug).toBeCalledWith('hello world', ['events'], { + event: { + duration: undefined, + end: undefined, + provider: 'test-adapting', + start: undefined, + }, + kibana: { + reporting: { + wins: 5000, + }, + }, + }); + }); + + it('captures timings between start and complete', () => { + const eventLogger = new EcsLogAdapter(logger, { event: { provider: 'test-adapting' } }); + eventLogger.startTiming(); + + const event = { kibana: { reporting: { wins: 9000 } } } as object & LogMeta; // an object that extends LogMeta + eventLogger.logEvent('hello duration', event); + + expect(logger.debug).toBeCalledWith('hello duration', ['events'], { + event: { + duration: 120000000000, + end: '2021-04-12T16:02:00.000Z', + provider: 'test-adapting', + start: '2021-04-12T16:00:00.000Z', + }, + kibana: { + reporting: { + wins: 9000, + }, + }, + }); + }); +}); diff --git a/x-pack/plugins/reporting/server/lib/event_logger/adapter.ts b/x-pack/plugins/reporting/server/lib/event_logger/adapter.ts new file mode 100644 index 0000000000000..c9487a79d9e70 --- /dev/null +++ b/x-pack/plugins/reporting/server/lib/event_logger/adapter.ts @@ -0,0 +1,57 @@ +/* + * 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 deepMerge from 'deepmerge'; +import { LogMeta } from 'src/core/server'; +import { LevelLogger } from '../level_logger'; +import { IReportingEventLogger } from './logger'; + +/** @internal */ +export class EcsLogAdapter implements IReportingEventLogger { + start?: Date; + end?: Date; + + /** + * This class provides a logging system to Reporting code, using a shape similar to the EventLog service. + * The logging action causes ECS data with Reporting metrics sent to DEBUG logs. + * + * @param {LevelLogger} logger - Reporting's wrapper of the core logger + * @param {Partial} properties - initial ECS data with template for Reporting metrics + */ + constructor(private logger: LevelLogger, private properties: Partial) {} + + logEvent(message: string, properties: LogMeta) { + if (this.start && !this.end) { + this.end = new Date(Date.now()); + } + + let duration: number | undefined; + if (this.end && this.start) { + duration = (this.end.valueOf() - this.start.valueOf()) * 1000000; // nanoseconds + } + + // add the derived properties for timing between "start" and "complete" logging calls + const newProperties: LogMeta = deepMerge(this.properties, { + event: { + duration, + start: this.start?.toISOString(), + end: this.end?.toISOString(), + }, + }); + + // sends an ECS object with Reporting metrics to the DEBUG logs + this.logger.debug(message, ['events'], deepMerge(newProperties, properties)); + } + + startTiming() { + this.start = new Date(Date.now()); + } + + stopTiming() { + this.end = new Date(Date.now()); + } +} diff --git a/x-pack/plugins/reporting/server/lib/event_logger/index.ts b/x-pack/plugins/reporting/server/lib/event_logger/index.ts index 566f0a21e2b05..f9c4c5574b3e1 100644 --- a/x-pack/plugins/reporting/server/lib/event_logger/index.ts +++ b/x-pack/plugins/reporting/server/lib/event_logger/index.ts @@ -5,9 +5,6 @@ * 2.0. */ -import { IEventLogService } from '../../../../event_log/server'; -import { PLUGIN_ID } from '../../../common/constants'; - export enum ActionType { SCHEDULE_TASK = 'schedule-task', CLAIM_TASK = 'claim-task', @@ -16,7 +13,5 @@ export enum ActionType { SAVE_REPORT = 'save-report', RETRY = 'retry', FAIL_REPORT = 'fail-report', -} -export function registerEventLogProviderActions(eventLog: IEventLogService) { - eventLog.registerProviderActions(PLUGIN_ID, Object.values(ActionType)); + EXECUTE_ERROR = 'execute-error', } diff --git a/x-pack/plugins/reporting/server/lib/event_logger/logger.test.ts b/x-pack/plugins/reporting/server/lib/event_logger/logger.test.ts index 21c4ee2d5e4cf..9a1c282a01a59 100644 --- a/x-pack/plugins/reporting/server/lib/event_logger/logger.test.ts +++ b/x-pack/plugins/reporting/server/lib/event_logger/logger.test.ts @@ -6,7 +6,7 @@ */ import { ConcreteTaskInstance } from '../../../../task_manager/server'; -import { eventLogServiceMock } from '../../../../event_log/server/mocks'; +import { createMockLevelLogger } from '../../test_helpers'; import { BasePayload } from '../../types'; import { Report } from '../store'; import { ReportingEventLogger, reportingEventLoggerFactory } from './logger'; @@ -21,7 +21,7 @@ describe('Event Logger', () => { let factory: ReportingEventLogger; beforeEach(() => { - factory = reportingEventLoggerFactory(eventLogServiceMock.create()); + factory = reportingEventLoggerFactory(createMockLevelLogger()); }); it(`should construct with an internal seed object`, () => { @@ -29,7 +29,6 @@ describe('Event Logger', () => { expect(logger.eventObj).toMatchInlineSnapshot(` Object { "event": Object { - "provider": "reporting", "timezone": "UTC", }, "kibana": Object { @@ -38,9 +37,6 @@ describe('Event Logger', () => { "jobType": "csv", }, }, - "log": Object { - "logger": "reporting", - }, "user": undefined, } `); @@ -51,7 +47,6 @@ describe('Event Logger', () => { expect(logger.eventObj).toMatchInlineSnapshot(` Object { "event": Object { - "provider": "reporting", "timezone": "UTC", }, "kibana": Object { @@ -60,9 +55,6 @@ describe('Event Logger', () => { "jobType": "csv", }, }, - "log": Object { - "logger": "reporting", - }, "user": Object { "name": "thundercat", }, @@ -77,7 +69,6 @@ describe('Event Logger', () => { expect(logger.eventObj).toMatchInlineSnapshot(` Object { "event": Object { - "provider": "reporting", "timezone": "UTC", }, "kibana": Object { @@ -89,9 +80,6 @@ describe('Event Logger', () => { "id": "some-task-id-123", }, }, - "log": Object { - "logger": "reporting", - }, "user": Object { "name": "thundercat", }, @@ -101,16 +89,16 @@ describe('Event Logger', () => { it(`logExecutionStart`, () => { const logger = new factory(mockReport); + jest.spyOn(logger.completionLogger, 'startTiming'); + jest.spyOn(logger.completionLogger, 'stopTiming'); const result = logger.logExecutionStart(); expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "execute-start", - "kind": "event", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "execute-start", "id": "12348", "jobType": "csv", }, @@ -119,23 +107,23 @@ describe('Event Logger', () => { `); expect(result.message).toMatchInlineSnapshot(`"starting csv execution"`); expect(logger.completionLogger.startTiming).toBeCalled(); + expect(logger.completionLogger.stopTiming).not.toBeCalled(); }); it(`logExecutionComplete`, () => { const logger = new factory(mockReport); + jest.spyOn(logger.completionLogger, 'startTiming'); + jest.spyOn(logger.completionLogger, 'stopTiming'); logger.logExecutionStart(); const result = logger.logExecutionComplete({ byteSize: 444 }); expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "execute-complete", - "kind": "metrics", - "outcome": "success", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "execute-complete", "byteSize": 444, "id": "12348", "jobType": "csv", @@ -154,13 +142,10 @@ describe('Event Logger', () => { expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "execute-complete", - "kind": "error", - "outcome": "failure", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "execute-error", "id": "12348", "jobType": "csv", }, @@ -176,12 +161,10 @@ describe('Event Logger', () => { expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "claim-task", - "kind": "event", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "claim-task", "id": "12348", "jobType": "csv", }, @@ -196,12 +179,10 @@ describe('Event Logger', () => { expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "fail-report", - "kind": "event", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "fail-report", "id": "12348", "jobType": "csv", }, @@ -215,12 +196,10 @@ describe('Event Logger', () => { expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "save-report", - "kind": "event", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "save-report", "id": "12348", "jobType": "csv", }, @@ -234,12 +213,10 @@ describe('Event Logger', () => { expect([result.event, result.kibana.reporting, result.message]).toMatchInlineSnapshot(` Array [ Object { - "action": "retry", - "kind": "event", - "provider": "reporting", "timezone": "UTC", }, Object { + "actionType": "retry", "id": "12348", "jobType": "csv", }, diff --git a/x-pack/plugins/reporting/server/lib/event_logger/logger.ts b/x-pack/plugins/reporting/server/lib/event_logger/logger.ts index 0ec864e36620b..ccdee24d1879e 100644 --- a/x-pack/plugins/reporting/server/lib/event_logger/logger.ts +++ b/x-pack/plugins/reporting/server/lib/event_logger/logger.ts @@ -6,16 +6,19 @@ */ import deepMerge from 'deepmerge'; -import { IEventLogger, IEventLogService } from '../../../../event_log/server'; +import { LogMeta } from 'src/core/server'; +import { LevelLogger } from '../'; import { PLUGIN_ID } from '../../../common/constants'; import { IReport } from '../store'; import { ActionType } from './'; +import { EcsLogAdapter } from './adapter'; import { ClaimedTask, CompletedExecution, ErrorAction, ExecuteError, FailedReport, + ReportingAction, SavedReport, ScheduledRetry, ScheduledTask, @@ -27,171 +30,162 @@ export interface ExecutionCompleteMetrics { byteSize: number; } +export interface IReportingEventLogger { + logEvent(message: string, properties: LogMeta): void; + startTiming(): void; + stopTiming(): void; +} + /** @internal */ -export function reportingEventLoggerFactory(eventLog: IEventLogService) { - const genericLogger = eventLog.getLogger({ event: { provider: PLUGIN_ID } }); +export function reportingEventLoggerFactory(logger: LevelLogger) { + const genericLogger = new EcsLogAdapter(logger, { event: { provider: PLUGIN_ID } }); return class ReportingEventLogger { readonly eventObj: { event: { timezone: string; - provider: 'reporting'; }; - kibana: { reporting: StartedExecution['kibana']['reporting']; task?: { id: string } }; - log: { logger: 'reporting' }; + kibana: { + reporting: ReportingAction['kibana']['reporting']; + task?: { id: string }; + }; user?: { name: string }; }; readonly report: IReport; readonly task?: { id: string }; - completionLogger: IEventLogger; + completionLogger: IReportingEventLogger; constructor(report: IReport, task?: { id: string }) { this.report = report; this.task = task; this.eventObj = { - event: { timezone: report.payload.browserTimezone, provider: 'reporting' }, + event: { timezone: report.payload.browserTimezone }, kibana: { reporting: { id: report._id, jobType: report.jobtype }, ...(task?.id ? { task: { id: task.id } } : undefined), }, - log: { logger: 'reporting' }, user: report.created_by ? { name: report.created_by } : undefined, }; // create a "complete" logger that will use EventLog helpers to calculate timings - this.completionLogger = eventLog.getLogger({ event: { provider: PLUGIN_ID } }); + this.completionLogger = new EcsLogAdapter(logger, { event: { provider: PLUGIN_ID } }); } logScheduleTask(): ScheduledTask { + const message = `queued report ${this.report._id}`; const event = deepMerge( { - message: `queued report ${this.report._id}`, - event: { kind: 'event', action: ActionType.SCHEDULE_TASK }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.SCHEDULE_TASK } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logExecutionStart(): StartedExecution { - this.completionLogger.startTiming(this.eventObj); + const message = `starting ${this.report.jobtype} execution`; + this.completionLogger.startTiming(); const event = deepMerge( { - message: `starting ${this.report.jobtype} execution`, - event: { kind: 'event', action: ActionType.EXECUTE_START }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.EXECUTE_START } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logExecutionComplete({ byteSize }: ExecutionCompleteMetrics): CompletedExecution { - this.completionLogger.stopTiming(this.eventObj); + const message = `completed ${this.report.jobtype} execution`; + this.completionLogger.stopTiming(); const event = deepMerge( { - message: `completed ${this.report.jobtype} execution`, - event: { - kind: 'metrics', - outcome: 'success', - action: ActionType.EXECUTE_COMPLETE, - }, - kibana: { reporting: { byteSize } }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.EXECUTE_COMPLETE, byteSize } }, } as Partial, this.eventObj ); - this.completionLogger.logEvent(event); + this.completionLogger.logEvent(message, event); return event; } logError(error: ErrorAction): ExecuteError { - interface LoggedErrorMessage { - message: string; - error: ExecuteError['error']; - event: Omit; - log: Omit; - } - const logErrorMessage: LoggedErrorMessage = { - message: error.message, + const message = `an error occurred`; + const logErrorMessage = { + message, + kibana: { reporting: { actionType: ActionType.EXECUTE_ERROR } }, error: { message: error.message, code: error.code, stack_trace: error.stack_trace, type: error.type, }, - event: { - kind: 'error', - outcome: 'failure', - action: ActionType.EXECUTE_COMPLETE, - }, - log: { level: 'error' }, - }; + } as Partial; const event = deepMerge(logErrorMessage, this.eventObj); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logClaimTask(): ClaimedTask { + const message = `claimed report ${this.report._id}`; const event = deepMerge( { - message: `claimed report ${this.report._id}`, - event: { kind: 'event', action: ActionType.CLAIM_TASK }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.CLAIM_TASK } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logReportFailure(): FailedReport { + const message = `report ${this.report._id} has failed`; const event = deepMerge( { - message: `report ${this.report._id} has failed`, - event: { kind: 'event', action: ActionType.FAIL_REPORT }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.FAIL_REPORT } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logReportSaved(): SavedReport { + const message = `saved report ${this.report._id}`; const event = deepMerge( { - message: `saved report ${this.report._id}`, - event: { kind: 'event', action: ActionType.SAVE_REPORT }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.SAVE_REPORT } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } logRetry(): ScheduledRetry { + const message = `scheduled retry for report ${this.report._id}`; const event = deepMerge( { - message: `scheduled retry for report ${this.report._id}`, - event: { kind: 'event', action: ActionType.RETRY }, - log: { level: 'info' }, + message, + kibana: { reporting: { actionType: ActionType.RETRY } }, } as Partial, this.eventObj ); - genericLogger.logEvent(event); + genericLogger.logEvent(message, event); return event; } }; diff --git a/x-pack/plugins/reporting/server/lib/event_logger/types.ts b/x-pack/plugins/reporting/server/lib/event_logger/types.ts index 1c31292d03e44..3ae06dfdb4775 100644 --- a/x-pack/plugins/reporting/server/lib/event_logger/types.ts +++ b/x-pack/plugins/reporting/server/lib/event_logger/types.ts @@ -5,31 +5,23 @@ * 2.0. */ +import { LogMeta } from 'src/core/server'; import { ActionType } from './'; -type ActionKind = 'event' | 'error' | 'metrics'; -type ActionOutcome = 'success' | 'failure'; - -interface ActionBase< - A extends ActionType, - K extends ActionKind, - O extends ActionOutcome, - EventProvider -> { +interface ActionBase { event: { - action: A; - kind: K; - outcome?: O; - provider: 'reporting'; timezone: string; }; - kibana: EventProvider & { task?: { id?: string } }; - user?: { name: string }; - log: { - logger: 'reporting'; - level: K extends 'error' ? 'error' : 'info'; - }; message: string; + kibana: { + reporting: { + actionType?: A; + id?: string; // "immediate download" exports have no ID + jobType: string; + byteSize?: number; + }; + } & { task?: { id?: string } }; + user?: { name: string }; } export interface ErrorAction { @@ -39,30 +31,15 @@ export interface ErrorAction { type?: string; } -type ReportingAction< - A extends ActionType, - K extends ActionKind, - O extends ActionOutcome = 'success' -> = ActionBase< - A, - K, - O, - { - reporting: { - id?: string; // "immediate download" exports have no ID - jobType: string; - byteSize?: number; - }; - } ->; +export type ReportingAction = ActionBase & LogMeta; -export type ScheduledTask = ReportingAction; -export type StartedExecution = ReportingAction; -export type CompletedExecution = ReportingAction; -export type SavedReport = ReportingAction; -export type ClaimedTask = ReportingAction; -export type ScheduledRetry = ReportingAction; -export type FailedReport = ReportingAction; -export type ExecuteError = ReportingAction & { +export type ScheduledTask = ReportingAction; +export type StartedExecution = ReportingAction; +export type CompletedExecution = ReportingAction; +export type SavedReport = ReportingAction; +export type ClaimedTask = ReportingAction; +export type ScheduledRetry = ReportingAction; +export type FailedReport = ReportingAction; +export type ExecuteError = ReportingAction & { error: ErrorAction; }; diff --git a/x-pack/plugins/reporting/server/lib/level_logger.ts b/x-pack/plugins/reporting/server/lib/level_logger.ts index 4985ae2d681d0..91cf6757dbee2 100644 --- a/x-pack/plugins/reporting/server/lib/level_logger.ts +++ b/x-pack/plugins/reporting/server/lib/level_logger.ts @@ -5,14 +5,14 @@ * 2.0. */ -import { LoggerFactory } from 'src/core/server'; +import { LoggerFactory, LogMeta } from 'src/core/server'; const trimStr = (toTrim: string) => { return typeof toTrim === 'string' ? toTrim.trim() : toTrim; }; export interface GenericLevelLogger { - debug: (msg: string) => void; + debug: (msg: string, tags: string[], meta: T) => void; info: (msg: string) => void; warning: (msg: string) => void; error: (msg: Error) => void; @@ -46,8 +46,9 @@ export class LevelLogger implements GenericLevelLogger { this.getLogger(tags).warn(msg); } - public debug(msg: string, tags: string[] = []) { - this.getLogger(tags).debug(msg); + // only "debug" logging supports the LogMeta for now... + public debug(msg: string, tags: string[] = [], meta?: T) { + this.getLogger(tags).debug(msg, meta); } public trace(msg: string, tags: string[] = []) { diff --git a/x-pack/plugins/reporting/server/plugin.ts b/x-pack/plugins/reporting/server/plugin.ts index 3b25fedd0d5fb..a0d4bfed7c7e0 100644 --- a/x-pack/plugins/reporting/server/plugin.ts +++ b/x-pack/plugins/reporting/server/plugin.ts @@ -11,7 +11,6 @@ import { ReportingCore } from './'; import { buildConfig, registerUiSettings, ReportingConfigType } from './config'; import { registerDeprecations } from './deprecations'; import { LevelLogger, ReportingStore } from './lib'; -import { registerEventLogProviderActions } from './lib/event_logger'; import { registerRoutes } from './routes'; import { setFieldFormats } from './services'; import type { @@ -38,7 +37,6 @@ export class ReportingPlugin public setup(core: CoreSetup, plugins: ReportingSetupDeps) { const { http, status } = core; - const reportingCore = new ReportingCore(this.logger, this.initContext); // prevent throwing errors in route handlers about async deps not being initialized @@ -60,7 +58,6 @@ export class ReportingPlugin ...plugins, }); - registerEventLogProviderActions(plugins.eventLog); registerUiSettings(core); registerDeprecations({ core, reportingCore }); registerReportingUsageCollector(reportingCore, plugins.usageCollection); diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts index aa065e7be52c7..49d92a0fe4448 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts @@ -40,10 +40,6 @@ export const createMockPluginSetup = ( taskManager: taskManagerMock.createSetup(), logger: createMockLevelLogger(), status: statusServiceMock.createSetupContract(), - eventLog: { - registerProviderActions: jest.fn(), - getLogger: jest.fn(() => ({ logEvent: jest.fn() })), - }, ...setupMock, }; }; diff --git a/x-pack/plugins/reporting/server/types.ts b/x-pack/plugins/reporting/server/types.ts index c695df6d0a410..cd28972f5941a 100644 --- a/x-pack/plugins/reporting/server/types.ts +++ b/x-pack/plugins/reporting/server/types.ts @@ -12,7 +12,6 @@ import { FieldFormatsStart } from 'src/plugins/field_formats/server'; import type { ScreenshotModePluginSetup } from 'src/plugins/screenshot_mode/server'; import type { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import type { Writable } from 'stream'; -import { IEventLogService } from '../../event_log/server'; import type { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import type { LicensingPluginStart } from '../../licensing/server'; import type { @@ -96,7 +95,6 @@ export interface ExportTypeDefinition< * @internal */ export interface ReportingSetupDeps { - eventLog: IEventLogService; features: FeaturesPluginSetup; screenshotMode: ScreenshotModePluginSetup; security?: SecurityPluginSetup; diff --git a/x-pack/plugins/reporting/tsconfig.json b/x-pack/plugins/reporting/tsconfig.json index 24db825856627..cb22a7d9e719a 100644 --- a/x-pack/plugins/reporting/tsconfig.json +++ b/x-pack/plugins/reporting/tsconfig.json @@ -20,7 +20,6 @@ { "path": "../../../src/plugins/ui_actions/tsconfig.json" }, { "path": "../../../src/plugins/usage_collection/tsconfig.json" }, { "path": "../../../src/plugins/field_formats/tsconfig.json" }, - { "path": "../event_log/tsconfig.json" }, { "path": "../features/tsconfig.json" }, { "path": "../licensing/tsconfig.json" }, { "path": "../screenshotting/tsconfig.json" }, diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/__snapshots__/event_log.snap b/x-pack/test/reporting_api_integration/reporting_and_security/__snapshots__/event_log.snap deleted file mode 100644 index 603ab78db8c13..0000000000000 --- a/x-pack/test/reporting_api_integration/reporting_and_security/__snapshots__/event_log.snap +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Reporting APIs Report generation event logging creates a completed action for a PDF report 1`] = ` -"\\"_id\\",\\"_index\\",\\"_score\\",category,\\"category.keyword\\",currency,\\"customer_first_name\\",\\"customer_first_name.keyword\\",\\"customer_full_name\\",\\"customer_full_name.keyword\\",\\"customer_gender\\",\\"customer_id\\",\\"customer_last_name\\",\\"customer_last_name.keyword\\",\\"customer_phone\\",\\"day_of_week\\",\\"day_of_week_i\\",email,\\"geoip.city_name\\",\\"geoip.continent_name\\",\\"geoip.country_iso_code\\",\\"geoip.location\\",\\"geoip.region_name\\",manufacturer,\\"manufacturer.keyword\\",\\"order_date\\",\\"order_id\\",\\"products._id\\",\\"products._id.keyword\\",\\"products.base_price\\",\\"products.base_unit_price\\",\\"products.category\\",\\"products.category.keyword\\",\\"products.created_on\\",\\"products.discount_amount\\",\\"products.discount_percentage\\",\\"products.manufacturer\\",\\"products.manufacturer.keyword\\",\\"products.min_price\\",\\"products.price\\",\\"products.product_id\\",\\"products.product_name\\",\\"products.product_name.keyword\\",\\"products.quantity\\",\\"products.sku\\",\\"products.tax_amount\\",\\"products.taxful_price\\",\\"products.taxless_price\\",\\"products.unit_discount_amount\\",sku,\\"taxful_total_price\\",\\"taxless_total_price\\",\\"total_quantity\\",\\"total_unique_products\\",type,user -zQMtOW0BH63Xcmy432DJ,ecommerce,1,\\"Men's Clothing\\",\\"Men's Clothing\\",EUR,Eddie,Eddie,\\"Eddie Underwood\\",\\"Eddie Underwood\\",MALE,38,Underwood,Underwood,\\"(empty)\\",Monday,0,\\"eddie@underwood-family.zzz\\",Cairo,Africa,EG,\\"POINT (31.3 30.1)\\",\\"Cairo Governorate\\",\\"Elitelligence, Oceanavigations\\",\\"Elitelligence, Oceanavigations\\",\\"Jul 7, 2019 @ 00:00:00.000\\",584677,\\"sold_product_584677_6283, sold_product_584677_19400\\",\\"sold_product_584677_6283, sold_product_584677_19400\\",\\"11.992, 24.984\\",\\"11.992, 24.984\\",\\"Men's Clothing, Men's Clothing\\",\\"Men's Clothing, Men's Clothing\\",\\"Dec 26, 2016 @ 00:00:00.000, Dec 26, 2016 @ 00:00:00.000\\",\\"0, 0\\",\\"0, 0\\",\\"Elitelligence, Oceanavigations\\",\\"Elitelligence, Oceanavigations\\",\\"6.352, 11.75\\",\\"11.992, 24.984\\",\\"6,283, 19,400\\",\\"Basic T-shirt - dark blue/white, Sweatshirt - grey multicolor\\",\\"Basic T-shirt - dark blue/white, Sweatshirt - grey multicolor\\",\\"1, 1\\",\\"ZO0549605496, ZO0299602996\\",\\"0, 0\\",\\"11.992, 24.984\\",\\"11.992, 24.984\\",\\"0, 0\\",\\"ZO0549605496, ZO0299602996\\",\\"36.969\\",\\"36.969\\",2,2,order,eddie -zgMtOW0BH63Xcmy432DJ,ecommerce,1,\\"Women's Clothing\\",\\"Women's Clothing\\",EUR,Mary,Mary,\\"Mary Bailey\\",\\"Mary Bailey\\",FEMALE,20,Bailey,Bailey,\\"(empty)\\",Sunday,6,\\"mary@bailey-family.zzz\\",Dubai,Asia,AE,\\"POINT (55.3 25.3)\\",Dubai,\\"Champion Arts, Pyramidustries\\",\\"Champion Arts, Pyramidustries\\",\\"Jul 6, 2019 @ 00:00:00.000\\",584021,\\"sold_product_584021_11238, sold_product_584021_20149\\",\\"sold_product_584021_11238, sold_product_584021_20149\\",\\"24.984, 28.984\\",\\"24.984, 28.984\\",\\"Women's Clothing, Women's Clothing\\",\\"Women's Clothing, Women's Clothing\\",\\"Dec 25, 2016 @ 00:00:00.000, Dec 25, 2016 @ 00:00:00.000\\",\\"0, 0\\",\\"0, 0\\",\\"Champion Arts, Pyramidustries\\",\\"Champion Arts, Pyramidustries\\",\\"11.75, 15.648\\",\\"24.984, 28.984\\",\\"11,238, 20,149\\",\\"Denim dress - black denim, Shorts - black\\",\\"Denim dress - black denim, Shorts - black\\",\\"1, 1\\",\\"ZO0489604896, ZO0185501855\\",\\"0, 0\\",\\"24.984, 28.984\\",\\"24.984, 28.984\\",\\"0, 0\\",\\"ZO0489604896, ZO0185501855\\",\\"53.969\\",\\"53.969\\",2,2,order,mary -zwMtOW0BH63Xcmy432DJ,ecommerce,1,\\"Women's Shoes, Women's Clothing\\",\\"Women's Shoes, Women's Clothing\\",EUR,Gwen,Gwen,\\"Gwen Butler\\",\\"Gwen Butler\\",FEMALE,26,Butler,Butler,\\"(empty)\\",Sunday,6,\\"gwen@butler-family.zzz\\",\\"Los Angeles\\",\\"North America\\",US,\\"POINT (-118.2 34.1)\\",California,\\"Low Tide Media, Oceanavigations\\",\\"Low Tide Media, Oceanavigations\\",\\"Jul 6, 2019 @ 00:00:00.000\\",584058,\\"sold_product_584058_22794, sold_product_584058_23386\\",\\"sold_product_584058_22794, sold_product_584058_23386\\",\\"100, 100\\",\\"100, 100\\",\\"Women's Shoes, Women's Clothing\\",\\"Women's Shoes, Women's Clothing\\",\\"Dec 25, 2016 @ 00:00:00.000, Dec 25, 2016 @ 00:00:00.000\\",\\"0, 0\\",\\"0, 0\\",\\"Low Tide Media, Oceanavigations\\",\\"Low Tide Media, Oceanavigations\\",\\"46, 54\\",\\"100, 100\\",\\"22,794, 23,386\\",\\"Boots - Midnight Blue, Short coat - white/black\\",\\"Boots - Midnight Blue, Short coat - white/black\\",\\"1, 1\\",\\"ZO0374603746, ZO0272202722\\",\\"0, 0\\",\\"100, 100\\",\\"100, 100\\",\\"0, 0\\",\\"ZO0374603746, ZO0272202722\\",200,200,2,2,order,gwen -0AMtOW0BH63Xcmy432DJ,ecommerce,1,\\"Women's Shoes, Women's Clothing\\",\\"Women's Shoes, Women's Clothing\\",EUR,Diane,Diane,\\"Diane Chandler\\",\\"Diane Chandler\\",FEMALE,22,Chandler,Chandler,\\"(empty)\\",Sunday,6,\\"diane@chandler-family.zzz\\",\\"-\\",Europe,GB,\\"POINT (-0.1 51.5)\\",\\"-\\",\\"Primemaster, Oceanavigations\\",\\"Primemaster, Oceanavigations\\",\\"Jul 6, 2019 @ 00:00:00.000\\",584093,\\"sold_product_584093_12304, sold_product_584093_19587\\",\\"sold_product_584093_12304, sold_product_584093_19587\\",\\"75, 100\\",\\"75, 100\\",\\"Women's Shoes, Women's Clothing\\",\\"Women's Shoes, Women's Clothing\\",\\"Dec 25, 2016 @ 00:00:00.000, Dec 25, 2016 @ 00:00:00.000\\",\\"0, 0\\",\\"0, 0\\",\\"Primemaster, Oceanavigations\\",\\"Primemaster, Oceanavigations\\",\\"34.5, 47\\",\\"75, 100\\",\\"12,304, 19,587\\",\\"High heeled sandals - argento, Classic coat - black\\",\\"High heeled sandals - argento, Classic coat - black\\",\\"1, 1\\",\\"ZO0360303603, ZO0272002720\\",\\"0, 0\\",\\"75, 100\\",\\"75, 100\\",\\"0, 0\\",\\"ZO0360303603, ZO0272002720\\",175,175,2,2,order,diane -0QMtOW0BH63Xcmy432DJ,ecommerce,1,\\"Men's Clothing, Men's Accessories\\",\\"Men's Clothing, Men's Accessories\\",EUR,Eddie,Eddie,\\"Eddie Weber\\",\\"Eddie Weber\\",MALE,38,Weber,Weber,\\"(empty)\\",Monday,0,\\"eddie@weber-family.zzz\\",Cairo,Africa,EG,\\"POINT (31.3 30.1)\\",\\"Cairo Governorate\\",Elitelligence,Elitelligence,\\"Jun 30, 2019 @ 00:00:00.000\\",574916,\\"sold_product_574916_11262, sold_product_574916_15713\\",\\"sold_product_574916_11262, sold_product_574916_15713\\",\\"60, 20.984\\",\\"60, 20.984\\",\\"Men's Clothing, Men's Accessories\\",\\"Men's Clothing, Men's Accessories\\",\\"Dec 19, 2016 @ 00:00:00.000, Dec 19, 2016 @ 00:00:00.000\\",\\"0, 0\\",\\"0, 0\\",\\"Elitelligence, Elitelligence\\",\\"Elitelligence, Elitelligence\\",\\"28.203, 10.703\\",\\"60, 20.984\\",\\"11,262, 15,713\\",\\"Winter jacket - black, Watch - green\\",\\"Winter jacket - black, Watch - green\\",\\"1, 1\\",\\"ZO0542505425, ZO0601306013\\",\\"0, 0\\",\\"60, 20.984\\",\\"60, 20.984\\",\\"0, 0\\",\\"ZO0542505425, ZO0601306013\\",81,81,2,2,order,eddie -" -`; diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/event_log.ts b/x-pack/test/reporting_api_integration/reporting_and_security/event_log.ts deleted file mode 100644 index 63317e7644021..0000000000000 --- a/x-pack/test/reporting_api_integration/reporting_and_security/event_log.ts +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 { omit } from 'lodash'; -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../ftr_provider_context'; - -// eslint-disable-next-line import/no-default-export -export default function ({ getService }: FtrProviderContext) { - const reportingAPI = getService('reportingAPI'); - const es = getService('es'); - - // FLAKY: https://github.com/elastic/kibana/issues/124649 - describe.skip('Report generation event logging', () => { - before(async () => { - await reportingAPI.initEcommerce(); - }); - - after(async () => { - await reportingAPI.teardownEcommerce(); - }); - - it('creates a completed action for a PDF report', async () => { - const res = await reportingAPI.generateCsv({ - browserTimezone: 'UTC', - title: 'Test-PDF', - objectType: 'search', - searchSource: { - version: true, - fields: [{ field: '*', include_unmapped: 'true' }], - index: '5193f870-d861-11e9-a311-0fa548c5f953', - }, - columns: [], - version: '7.16.0', - }); - expect(res.status).to.eql(200); - expect(res.body.path).to.match(/download/); - - const { path } = res.body; - - // wait for the the pending job to complete - await reportingAPI.waitForJobToFinish(path); - - const csvFile = await reportingAPI.getCompletedJobOutput(path); - expectSnapshot(csvFile).toMatch(); - - // search for the raw event log data - const events = await es.search<{ event: any; kibana: { reporting: any } }>({ - index: '.kibana-event-log*', - filter_path: 'hits.hits._source.event,hits.hits._source.kibana', - query: { - bool: { - filter: [ - { - bool: { - must: [ - { term: { 'event.provider': 'reporting' } }, - { term: { 'event.action': 'execute-complete' } }, - ], - }, - }, - ], - }, - }, - sort: [{ '@timestamp': { order: 'desc' } }] as unknown as string[], - size: 1, - }); - - // validate the log has the expected fields with expected values - const logSource = events.hits.hits[0]._source; - expect(omit(logSource?.kibana.reporting, 'id')).to.eql({ - byteSize: 5943, - jobType: 'csv_searchsource', - }); - expect(omit(logSource?.event, ['duration', 'start', 'end'])).to.eql({ - action: 'execute-complete', - kind: 'metrics', - outcome: 'success', - provider: 'reporting', - timezone: 'UTC', - }); - }); - }); -} diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/index.ts b/x-pack/test/reporting_api_integration/reporting_and_security/index.ts index e2f70eed3a508..02a2915fffd60 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/index.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/index.ts @@ -24,7 +24,6 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./bwc_existing_indexes')); loadTestFile(require.resolve('./security_roles_privileges')); loadTestFile(require.resolve('./download_csv_dashboard')); - loadTestFile(require.resolve('./event_log')); loadTestFile(require.resolve('./generate_csv_discover')); loadTestFile(require.resolve('./network_policy')); loadTestFile(require.resolve('./spaces'));