aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/logger/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'lib/logger/index.ts')
-rw-r--r--lib/logger/index.ts192
1 files changed, 75 insertions, 117 deletions
diff --git a/lib/logger/index.ts b/lib/logger/index.ts
index f066e05f97b..a120c4a4584 100644
--- a/lib/logger/index.ts
+++ b/lib/logger/index.ts
@@ -6,9 +6,8 @@ import upath from 'upath';
import cmdSerializer from './cmd-serializer';
import configSerializer from './config-serializer';
import errSerializer from './err-serializer';
-import { once, reset as onceReset } from './once';
import { RenovateStream } from './pretty-stdout';
-import { getRemappedLevel } from './remap';
+import { RenovateLogger } from './renovate-logger';
import type { BunyanRecord, Logger } from './types';
import {
ProblemStream,
@@ -17,161 +16,120 @@ import {
withSanitizer,
} from './utils';
-let logContext: string = getEnv('LOG_CONTEXT') ?? nanoid();
-let curMeta: Record<string, unknown> = {};
-
const problems = new ProblemStream();
-
let stdoutLevel = validateLogLevel(getEnv('LOG_LEVEL'), 'info');
-const stdout: bunyan.Stream = {
- name: 'stdout',
- level: stdoutLevel,
- stream: process.stdout,
-};
export function logLevel(): bunyan.LogLevelString {
return stdoutLevel;
}
-// istanbul ignore if: not testable
-if (getEnv('LOG_FORMAT') !== 'json') {
- // TODO: typings (#9615)
- const prettyStdOut = new RenovateStream() as any;
- prettyStdOut.pipe(process.stdout);
- stdout.stream = prettyStdOut;
- stdout.type = 'raw';
-}
-
-const bunyanLogger = bunyan.createLogger({
- name: 'renovate',
- serializers: {
- body: configSerializer,
- cmd: cmdSerializer,
- config: configSerializer,
- migratedConfig: configSerializer,
- originalConfig: configSerializer,
- presetConfig: configSerializer,
- oldConfig: configSerializer,
- newConfig: configSerializer,
- err: errSerializer,
- },
- streams: [
- stdout,
- {
- name: 'problems',
- level: 'warn' as bunyan.LogLevel,
- stream: problems as any,
- type: 'raw',
- },
- ].map(withSanitizer),
-});
-
-const logFactory = (
- _level: bunyan.LogLevelString,
-): ((p1: unknown, p2: unknown) => void) => {
- return (p1: any, p2: any): void => {
- let level = _level;
- if (p2) {
- // meta and msg provided
- const msg = p2;
- const meta: Record<string, unknown> = { logContext, ...curMeta, ...p1 };
- const remappedLevel = getRemappedLevel(msg);
- // istanbul ignore if: not testable
- if (remappedLevel) {
- meta.oldLevel = level;
- level = remappedLevel;
- }
- bunyanLogger[level](meta, msg);
- } else if (is.string(p1)) {
- // only message provided
- const msg = p1;
- const meta: Record<string, unknown> = { logContext, ...curMeta };
- const remappedLevel = getRemappedLevel(msg);
- // istanbul ignore if: not testable
- if (remappedLevel) {
- meta.oldLevel = level;
- level = remappedLevel;
- }
- bunyanLogger[level](meta, msg);
- } else {
- // only meta provided
- bunyanLogger[level]({ logContext, ...curMeta, ...p1 });
- }
+export function createDefaultStreams(
+ stdoutLevel: bunyan.LogLevelString,
+ problems: ProblemStream,
+ logFile: string | undefined,
+): bunyan.Stream[] {
+ const stdout: bunyan.Stream = {
+ name: 'stdout',
+ level: stdoutLevel,
+ stream: process.stdout,
};
-};
-
-const loggerLevels: bunyan.LogLevelString[] = [
- 'trace',
- 'debug',
- 'info',
- 'warn',
- 'error',
- 'fatal',
-];
-
-export const logger: Logger = { once: { reset: onceReset } } as any;
-
-loggerLevels.forEach((loggerLevel) => {
- logger[loggerLevel] = logFactory(loggerLevel) as never;
-
- const logOnceFn = (p1: any, p2: any): void => {
- once(() => {
- const logFn = logger[loggerLevel];
- if (is.undefined(p2)) {
- logFn(p1);
- } else {
- logFn(p1, p2);
- }
- }, logOnceFn);
+
+ // istanbul ignore if: not testable
+ if (getEnv('LOG_FORMAT') !== 'json') {
+ // TODO: typings (#9615)
+ const prettyStdOut = new RenovateStream() as any;
+ prettyStdOut.pipe(process.stdout);
+ stdout.stream = prettyStdOut;
+ stdout.type = 'raw';
+ }
+
+ const problemsStream: bunyan.Stream = {
+ name: 'problems',
+ level: 'warn' as bunyan.LogLevel,
+ stream: problems as any,
+ type: 'raw',
};
- logger.once[loggerLevel] = logOnceFn as never;
-});
-const logFile = getEnv('LOG_FILE');
-// istanbul ignore if: not easily testable
-if (is.string(logFile)) {
- // ensure log file directory exists
+ // istanbul ignore next: not easily testable
+ const logFileStream: bunyan.Stream | undefined = is.string(logFile)
+ ? createLogFileStream(logFile)
+ : undefined;
+
+ return [stdout, problemsStream, logFileStream].filter(
+ Boolean,
+ ) as bunyan.Stream[];
+}
+
+// istanbul ignore next: not easily testable
+function createLogFileStream(logFile: string): bunyan.Stream {
+ // Ensure log file directory exists
const directoryName = upath.dirname(logFile);
fs.ensureDirSync(directoryName);
- addStream({
+ return {
name: 'logfile',
path: logFile,
level: validateLogLevel(getEnv('LOG_FILE_LEVEL'), 'debug'),
+ };
+}
+
+function serializedSanitizedLogger(streams: bunyan.Stream[]): bunyan {
+ return bunyan.createLogger({
+ name: 'renovate',
+ serializers: {
+ body: configSerializer,
+ cmd: cmdSerializer,
+ config: configSerializer,
+ migratedConfig: configSerializer,
+ originalConfig: configSerializer,
+ presetConfig: configSerializer,
+ oldConfig: configSerializer,
+ newConfig: configSerializer,
+ err: errSerializer,
+ },
+ streams: streams.map(withSanitizer),
});
}
+const defaultStreams = createDefaultStreams(
+ stdoutLevel,
+ problems,
+ getEnv('LOG_FILE'),
+);
+
+const bunyanLogger = serializedSanitizedLogger(defaultStreams);
+const logContext = getEnv('LOG_CONTEXT') ?? nanoid();
+const loggerInternal = new RenovateLogger(bunyanLogger, logContext, {});
+
+export const logger: Logger = loggerInternal;
+
export function setContext(value: string): void {
- logContext = value;
+ loggerInternal.logContext = value;
}
export function getContext(): any {
- return logContext;
+ return loggerInternal.logContext;
}
// setMeta overrides existing meta, may remove fields if no longer existing
export function setMeta(obj: Record<string, unknown>): void {
- curMeta = { ...obj };
+ loggerInternal.setMeta(obj);
}
// addMeta overrides or adds fields but does not remove any
export function addMeta(obj: Record<string, unknown>): void {
- curMeta = { ...curMeta, ...obj };
+ loggerInternal.addMeta(obj);
}
// removeMeta removes the provided fields from meta
export function removeMeta(fields: string[]): void {
- Object.keys(curMeta).forEach((key) => {
- if (fields.includes(key)) {
- delete curMeta[key];
- }
- });
+ loggerInternal.removeMeta(fields);
}
export /* istanbul ignore next */ function addStream(
stream: bunyan.Stream,
): void {
- bunyanLogger.addStream(withSanitizer(stream));
+ loggerInternal.addStream(stream);
}
/**