feat(logging): add log level env variable (#2299)

This commit is contained in:
Meier Lukas
2025-02-18 22:54:15 +01:00
committed by GitHub
parent 6420feee72
commit 67d48e11d7
31 changed files with 202 additions and 183 deletions

10
packages/log/src/env.ts Normal file
View File

@@ -0,0 +1,10 @@
import { z } from "zod";
import { createEnv } from "@homarr/env";
export const env = createEnv({
server: {
LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),
},
experimental__runtimeEnv: process.env,
});

View File

@@ -1,4 +0,0 @@
import type { Logger } from "winston";
// The following is just to make prettier happy
export const logger: Logger = undefined as unknown as Logger;

View File

@@ -1,12 +1,14 @@
import type { transport as Transport } from "winston";
import winston, { format, transports } from "winston";
import { RedisTransport } from "./redis-transport.mjs";
import { env } from "./env";
import { RedisTransport } from "./redis-transport";
const logMessageFormat = format.printf(({ level, message, timestamp }) => {
return `${timestamp} ${level}: ${message}`;
return `${timestamp as string} ${level}: ${message as string}`;
});
const logTransports = [new transports.Console()];
const logTransports: Transport[] = [new transports.Console()];
// Only add the Redis transport if we are not in CI
if (!(Boolean(process.env.CI) || Boolean(process.env.DISABLE_REDIS_LOGS))) {
@@ -16,6 +18,7 @@ if (!(Boolean(process.env.CI) || Boolean(process.env.DISABLE_REDIS_LOGS))) {
const logger = winston.createLogger({
format: format.combine(format.colorize(), format.timestamp(), logMessageFormat),
transports: logTransports,
level: env.LOG_LEVEL,
});
export { logger };

View File

@@ -1,42 +0,0 @@
void (async () => {
const { logger } = await import("./index.mjs");
const nextLogger = require("next/dist/build/output/log");
const getWinstonMethodForConsole = (consoleMethod) => {
switch (consoleMethod) {
case "error":
return (...messages) => logger.error(messages.join(" "));
case "warn":
return (...messages) => logger.warn(messages.join(" "));
case "debug":
return (...messages) => logger.debug(messages.join(" "));
case "log":
case "info":
default:
return (...messages) => logger.info(messages.join(" "));
}
};
const consoleMethods = ["log", "debug", "info", "warn", "error"];
consoleMethods.forEach((method) => {
console[method] = getWinstonMethodForConsole(method);
});
const getWinstonMethodForNext = (nextMethod) => {
switch (nextMethod) {
case "error":
return (...messages) => logger.error(messages.join(" "));
case "warn":
return (...messages) => logger.warn(messages.join(" "));
case "trace":
return (...messages) => logger.info(messages.join(" "));
default:
return (...messages) => logger.info(messages.join(" "));
}
};
Object.keys(nextLogger.prefixes).forEach((method) => {
nextLogger[method] = getWinstonMethodForNext(method);
});
})();

View File

@@ -7,15 +7,12 @@ import Transport from "winston-transport";
// of the base functionality and `.exceptions.handle()`.
//
export class RedisTransport extends Transport {
/** @type {Redis} */
redis;
private redis: Redis | null = null;
/**
* Log the info to the Redis channel
* @param {{ message: string; timestamp: string; level: string; }} info
* @param {() => void} callback
*/
log(info, callback) {
log(info: { message: string; timestamp: string; level: string }, callback: () => void) {
setImmediate(() => {
this.emit("logged", info);
});