-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
create kbn-legacy-logging package #77678
Changes from all commits
3ad4c93
73122e5
87ca167
f6dd86c
ba67eb7
e2e1615
bd0c68d
76f4f27
e54b7d9
361deda
5d7b70a
6bd16cf
8ddc262
f6c67de
8382a09
56e3ea1
4b8a661
5f0471d
294a05a
f2766e5
0dd3b23
5a37913
a60d262
dbbe2e5
389dfe9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# @kbn/legacy-logging | ||
|
||
This package contains the implementation of the legacy logging | ||
system, based on `@hapi/good` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "@kbn/legacy-logging", | ||
"version": "1.0.0", | ||
"private": true, | ||
"license": "Apache-2.0", | ||
"main": "./target/index.js", | ||
"scripts": { | ||
"build": "tsc", | ||
"kbn:bootstrap": "yarn build", | ||
"kbn:watch": "yarn build --watch" | ||
}, | ||
"dependencies": { | ||
"@kbn/std": "link:../kbn-std" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export { LegacyLoggingConfig, legacyLoggingConfigSchema } from './schema'; | ||
export { attachMetaData } from './metadata'; | ||
export { setupLoggingRotate } from './rotate'; | ||
export { setupLogging, reconfigureLogging } from './setup_logging'; | ||
export { getLoggingConfiguration } from './get_logging_config'; | ||
export { LegacyLoggingServer } from './legacy_logging_server'; |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -17,29 +17,40 @@ | |||||||
* under the License. | ||||||||
*/ | ||||||||
|
||||||||
import { ServerExtType } from '@hapi/hapi'; | ||||||||
import Podium from '@hapi/podium'; | ||||||||
// @ts-expect-error: implicit any for JS file | ||||||||
import { Config } from '../../../../legacy/server/config'; | ||||||||
// @ts-expect-error: implicit any for JS file | ||||||||
import { setupLogging } from '../../../../legacy/server/logging'; | ||||||||
import { LogLevel, LogRecord } from '../../logging'; | ||||||||
import { LegacyVars } from '../../types'; | ||||||||
|
||||||||
export const metadataSymbol = Symbol('log message with metadata'); | ||||||||
export function attachMetaData(message: string, metadata: LegacyVars = {}) { | ||||||||
return { | ||||||||
[metadataSymbol]: { | ||||||||
message, | ||||||||
metadata, | ||||||||
}, | ||||||||
}; | ||||||||
import { ServerExtType, Server } from '@hapi/hapi'; | ||||||||
import Podium from 'podium'; | ||||||||
import { setupLogging } from './setup_logging'; | ||||||||
import { attachMetaData } from './metadata'; | ||||||||
import { legacyLoggingConfigSchema } from './schema'; | ||||||||
|
||||||||
// these LogXXX types are duplicated to avoid a cross dependency with the @kbn/logging package. | ||||||||
// typescript will error if they diverge at some point. | ||||||||
type LogLevelId = 'all' | 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace' | 'off'; | ||||||||
|
||||||||
interface LogLevel { | ||||||||
id: LogLevelId; | ||||||||
value: number; | ||||||||
} | ||||||||
|
||||||||
export interface LogRecord { | ||||||||
timestamp: Date; | ||||||||
level: LogLevel; | ||||||||
context: string; | ||||||||
message: string; | ||||||||
error?: Error; | ||||||||
meta?: { [name: string]: any }; | ||||||||
pid: number; | ||||||||
} | ||||||||
|
||||||||
const isEmptyObject = (obj: object) => Object.keys(obj).length === 0; | ||||||||
|
||||||||
function getDataToLog(error: Error | undefined, metadata: object, message: string) { | ||||||||
if (error) return error; | ||||||||
if (!isEmptyObject(metadata)) return attachMetaData(message, metadata); | ||||||||
if (error) { | ||||||||
return error; | ||||||||
} | ||||||||
if (!isEmptyObject(metadata)) { | ||||||||
return attachMetaData(message, metadata); | ||||||||
} | ||||||||
return message; | ||||||||
} | ||||||||
|
||||||||
|
@@ -50,7 +61,7 @@ interface PluginRegisterParams { | |||||||
options: PluginRegisterParams['options'] | ||||||||
) => Promise<void>; | ||||||||
}; | ||||||||
options: LegacyVars; | ||||||||
options: Record<string, any>; | ||||||||
} | ||||||||
|
||||||||
/** | ||||||||
|
@@ -84,22 +95,19 @@ export class LegacyLoggingServer { | |||||||
|
||||||||
private onPostStopCallback?: () => void; | ||||||||
|
||||||||
constructor(legacyLoggingConfig: Readonly<LegacyVars>) { | ||||||||
constructor(legacyLoggingConfig: any) { | ||||||||
// We set `ops.interval` to max allowed number and `ops` filter to value | ||||||||
// that doesn't exist to avoid logging of ops at all, if turned on it will be | ||||||||
// logged by the "legacy" Kibana. | ||||||||
const config = { | ||||||||
logging: { | ||||||||
...legacyLoggingConfig, | ||||||||
events: { | ||||||||
...legacyLoggingConfig.events, | ||||||||
ops: '__no-ops__', | ||||||||
}, | ||||||||
const { value: loggingConfig } = legacyLoggingConfigSchema.validate({ | ||||||||
...legacyLoggingConfig, | ||||||||
events: { | ||||||||
...legacyLoggingConfig.events, | ||||||||
ops: '__no-ops__', | ||||||||
}, | ||||||||
ops: { interval: 2147483647 }, | ||||||||
}; | ||||||||
}); | ||||||||
|
||||||||
setupLogging(this, Config.withDefaultSchema(config)); | ||||||||
setupLogging((this as unknown) as Server, loggingConfig, 2147483647); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we expect There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only import of this package in core (soon in kibana/src/core/server/legacy/logging/appenders/legacy_appender.ts Lines 48 to 50 in ab92bbb
The idea was to change the file to use a dynamic Note that the main goal to not load the legacy logging system / hapi when importing the config service was for the apm script instrumentation, which is no longer concerned by the problem, as it will have its own loader to ensure we are not importing any module we want to instrument at all (#77855) |
||||||||
} | ||||||||
|
||||||||
public register({ plugin: { register }, options }: PluginRegisterParams): Promise<void> { | ||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
import { EventData, isEventData } from './metadata'; | ||
|
||
export interface BaseEvent { | ||
event: string; | ||
timestamp: number; | ||
pid: number; | ||
tags?: string[]; | ||
} | ||
|
||
export interface ResponseEvent extends BaseEvent { | ||
event: 'response'; | ||
method: 'GET' | 'POST' | 'PUT' | 'DELETE'; | ||
statusCode: number; | ||
path: string; | ||
headers: Record<string, string | string[]>; | ||
responsePayload: string; | ||
responseTime: string; | ||
query: Record<string, any>; | ||
} | ||
|
||
export interface OpsEvent extends BaseEvent { | ||
event: 'ops'; | ||
os: { | ||
load: string[]; | ||
}; | ||
proc: Record<string, any>; | ||
load: string; | ||
} | ||
|
||
export interface ErrorEvent extends BaseEvent { | ||
event: 'error'; | ||
error: Error; | ||
url: string; | ||
} | ||
|
||
export interface UndeclaredErrorEvent extends BaseEvent { | ||
error: Error; | ||
} | ||
|
||
export interface LogEvent extends BaseEvent { | ||
data: EventData; | ||
} | ||
|
||
export interface UnkownEvent extends BaseEvent { | ||
data: string | Record<string, any>; | ||
} | ||
|
||
export type AnyEvent = | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎉 |
||
| ResponseEvent | ||
| OpsEvent | ||
| ErrorEvent | ||
| UndeclaredErrorEvent | ||
| LogEvent | ||
| UnkownEvent; | ||
|
||
export const isResponseEvent = (e: AnyEvent): e is ResponseEvent => e.event === 'response'; | ||
export const isOpsEvent = (e: AnyEvent): e is OpsEvent => e.event === 'ops'; | ||
export const isErrorEvent = (e: AnyEvent): e is ErrorEvent => e.event === 'error'; | ||
export const isLogEvent = (e: AnyEvent): e is LogEvent => isEventData((e as LogEvent).data); | ||
export const isUndeclaredErrorEvent = (e: AnyEvent): e is UndeclaredErrorEvent => | ||
(e as any).error instanceof Error; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a Readme that this package is a temporary workaround until we migrate logging to the KP?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more planning to keep it there until we totally get rid of the legacy logging system in 8.0 tbh. It will be way easier to delete it with all the code being centralized in this package. Was that what you meant?
edit: oh, I guess you mean the server event logging part. But there is the same issue. We have to keep support of the legacy logging format, meaning that the module won't go away before 8.0.