import { appConfig } from './config.js';
export enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3,
}
const logLevelMap: Record<string, LogLevel> = {
debug: LogLevel.DEBUG,
info: LogLevel.INFO,
warn: LogLevel.WARN,
error: LogLevel.ERROR,
};
class Logger {
private currentLevel: LogLevel;
constructor() {
this.currentLevel = logLevelMap[appConfig.server.logLevel] ?? LogLevel.INFO;
}
private shouldLog(level: LogLevel): boolean {
return level >= this.currentLevel;
}
private formatMessage(level: string, message: string, meta?: unknown): string {
const timestamp = new Date().toISOString();
const baseMessage = `[${timestamp}] ${level.toUpperCase()}: ${message}`;
if (meta !== undefined) {
const metaString = typeof meta === 'object'
? JSON.stringify(meta, null, 2)
: String(meta);
return `${baseMessage}\n${metaString}`;
}
return baseMessage;
}
debug(message: string, meta?: unknown): void {
if (this.shouldLog(LogLevel.DEBUG)) {
// eslint-disable-next-line no-console
console.debug(this.formatMessage('debug', message, meta));
}
}
info(message: string, meta?: unknown): void {
if (this.shouldLog(LogLevel.INFO)) {
// eslint-disable-next-line no-console
console.info(this.formatMessage('info', message, meta));
}
}
warn(message: string, meta?: unknown): void {
if (this.shouldLog(LogLevel.WARN)) {
// eslint-disable-next-line no-console
console.warn(this.formatMessage('warn', message, meta));
}
}
error(message: string, meta?: unknown): void {
if (this.shouldLog(LogLevel.ERROR)) {
// eslint-disable-next-line no-console
console.error(this.formatMessage('error', message, meta));
}
}
setLevel(level: LogLevel): void {
this.currentLevel = level;
}
}
export const logger = new Logger();