From 42b448b0e5f7d3fc3ff12bf8d00ab95710f60a03 Mon Sep 17 00:00:00 2001
From: Michael Kriese <michael.kriese@visualon.de>
Date: Wed, 13 Nov 2024 18:58:19 +0100
Subject: [PATCH] feat(logger): prefix log env settings with `RENOVATE_`
 (#32499)

Co-authored-by: Rhys Arkins <rhys@arkins.net>
---
 lib/logger/index.spec.ts         |  3 ++
 lib/logger/index.ts              | 48 ++++++++++++++++++++++----------
 lib/logger/utils.ts              |  6 ++++
 lib/workers/global/index.spec.ts |  1 +
 lib/workers/global/index.ts      |  7 ++---
 5 files changed, 46 insertions(+), 19 deletions(-)

diff --git a/lib/logger/index.spec.ts b/lib/logger/index.spec.ts
index 3fa2fbd10a..a2eb3e3beb 100644
--- a/lib/logger/index.spec.ts
+++ b/lib/logger/index.spec.ts
@@ -10,6 +10,7 @@ import {
   getContext,
   getProblems,
   levels,
+  logLevel,
   logger,
   removeMeta,
   setContext,
@@ -53,7 +54,9 @@ describe('logger/index', () => {
   });
 
   it('sets level', () => {
+    expect(logLevel()).toBeDefined(); // depends on passed env
     expect(() => levels('stdout', 'debug')).not.toThrow();
+    expect(logLevel()).toBe('debug');
   });
 
   it('saves problems', () => {
diff --git a/lib/logger/index.ts b/lib/logger/index.ts
index 504e9b1a2c..f066e05f97 100644
--- a/lib/logger/index.ts
+++ b/lib/logger/index.ts
@@ -10,26 +10,31 @@ import { once, reset as onceReset } from './once';
 import { RenovateStream } from './pretty-stdout';
 import { getRemappedLevel } from './remap';
 import type { BunyanRecord, Logger } from './types';
-import { ProblemStream, validateLogLevel, withSanitizer } from './utils';
-
-let logContext: string = process.env.LOG_CONTEXT ?? nanoid();
+import {
+  ProblemStream,
+  getEnv,
+  validateLogLevel,
+  withSanitizer,
+} from './utils';
+
+let logContext: string = getEnv('LOG_CONTEXT') ?? nanoid();
 let curMeta: Record<string, unknown> = {};
 
 const problems = new ProblemStream();
 
-// istanbul ignore if: not easily testable
-if (is.string(process.env.LOG_LEVEL)) {
-  process.env.LOG_LEVEL = process.env.LOG_LEVEL.toLowerCase().trim();
-}
-
+let stdoutLevel = validateLogLevel(getEnv('LOG_LEVEL'), 'info');
 const stdout: bunyan.Stream = {
   name: 'stdout',
-  level: validateLogLevel(process.env.LOG_LEVEL, 'info'),
+  level: stdoutLevel,
   stream: process.stdout,
 };
 
+export function logLevel(): bunyan.LogLevelString {
+  return stdoutLevel;
+}
+
 // istanbul ignore if: not testable
-if (process.env.LOG_FORMAT !== 'json') {
+if (getEnv('LOG_FORMAT') !== 'json') {
   // TODO: typings (#9615)
   const prettyStdOut = new RenovateStream() as any;
   prettyStdOut.pipe(process.stdout);
@@ -122,16 +127,17 @@ loggerLevels.forEach((loggerLevel) => {
   logger.once[loggerLevel] = logOnceFn as never;
 });
 
+const logFile = getEnv('LOG_FILE');
 // istanbul ignore if: not easily testable
-if (is.string(process.env.LOG_FILE)) {
+if (is.string(logFile)) {
   // ensure log file directory exists
-  const directoryName = upath.dirname(process.env.LOG_FILE);
+  const directoryName = upath.dirname(logFile);
   fs.ensureDirSync(directoryName);
 
   addStream({
     name: 'logfile',
-    path: process.env.LOG_FILE,
-    level: validateLogLevel(process.env.LOG_FILE_LEVEL, 'debug'),
+    path: logFile,
+    level: validateLogLevel(getEnv('LOG_FILE_LEVEL'), 'debug'),
   });
 }
 
@@ -168,8 +174,20 @@ export /* istanbul ignore next */ function addStream(
   bunyanLogger.addStream(withSanitizer(stream));
 }
 
-export function levels(name: string, level: bunyan.LogLevel): void {
+/**
+ * For testing purposes only
+ * @param name stream name
+ * @param level log level
+ * @private
+ */
+export function levels(
+  name: 'stdout' | 'logfile',
+  level: bunyan.LogLevelString,
+): void {
   bunyanLogger.levels(name, level);
+  if (name === 'stdout') {
+    stdoutLevel = level;
+  }
 }
 
 export function getProblems(): BunyanRecord[] {
diff --git a/lib/logger/utils.ts b/lib/logger/utils.ts
index f04c0f8132..5b2d512601 100644
--- a/lib/logger/utils.ts
+++ b/lib/logger/utils.ts
@@ -333,3 +333,9 @@ export function sanitizeUrls(text: string): string {
     })
     .replace(dataUriCredRe, '$1**redacted**');
 }
+
+export function getEnv(key: string): string | undefined {
+  return [process.env[`RENOVATE_${key}`], process.env[key]]
+    .map((v) => v?.toLowerCase().trim())
+    .find(is.nonEmptyStringAndNotWhitespace);
+}
diff --git a/lib/workers/global/index.spec.ts b/lib/workers/global/index.spec.ts
index dd9c31464e..9348676f0d 100644
--- a/lib/workers/global/index.spec.ts
+++ b/lib/workers/global/index.spec.ts
@@ -43,6 +43,7 @@ const initPlatform = jest.spyOn(platform, 'initPlatform');
 describe('workers/global/index', () => {
   beforeEach(() => {
     logger.getProblems.mockImplementation(() => []);
+    logger.logLevel.mockImplementation(() => 'info');
     initPlatform.mockImplementation((input) => Promise.resolve(input));
     delete process.env.AWS_SECRET_ACCESS_KEY;
     delete process.env.AWS_SESSION_TOKEN;
diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts
index fd233ecb61..0ef5d1c870 100644
--- a/lib/workers/global/index.ts
+++ b/lib/workers/global/index.ts
@@ -17,7 +17,7 @@ import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages';
 import { pkg } from '../../expose.cjs';
 import { instrument } from '../../instrumentation';
 import { exportStats, finalizeReport } from '../../instrumentation/reporting';
-import { getProblems, logger, setMeta } from '../../logger';
+import { getProblems, logLevel, logger, setMeta } from '../../logger';
 import { setGlobalLogLevelRemaps } from '../../logger/remap';
 import * as hostRules from '../../util/host-rules';
 import * as queue from '../../util/http/queue';
@@ -228,10 +228,9 @@ export async function start(): Promise<number> {
     }
   } finally {
     await globalFinalize(config!);
-    const logLevel = process.env.LOG_LEVEL ?? 'info';
-    if (logLevel === 'info') {
+    if (logLevel() === 'info') {
       logger.info(
-        `Renovate was run at log level "${logLevel}". Set LOG_LEVEL=debug in environment variables to see extended debug logs.`,
+        `Renovate was run at log level "${logLevel()}". Set LOG_LEVEL=debug in environment variables to see extended debug logs.`,
       );
     }
   }
-- 
GitLab