logger.ts•2.06 kB
export enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3,
}
export class Logger {
private static instance: Logger;
private logLevel: LogLevel;
private constructor() {
const level = process.env.LOG_LEVEL?.toLowerCase() || 'info';
this.logLevel = this.parseLogLevel(level);
}
static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
private parseLogLevel(level: string): LogLevel {
switch (level) {
case 'debug':
return LogLevel.DEBUG;
case 'info':
return LogLevel.INFO;
case 'warn':
return LogLevel.WARN;
case 'error':
return LogLevel.ERROR;
default:
return LogLevel.INFO;
}
}
private shouldLog(level: LogLevel): boolean {
return level >= this.logLevel;
}
private formatMessage(level: string, message: string, ...args: any[]): string {
const timestamp = new Date().toISOString();
const argsStr = args.length > 0 ? ' ' + args.map(arg =>
typeof arg === 'object' ? JSON.stringify(arg) : String(arg)
).join(' ') : '';
return `[${timestamp}] [${level}] ${message}${argsStr}`;
}
debug(message: string, ...args: any[]): void {
if (this.shouldLog(LogLevel.DEBUG)) {
console.error(this.formatMessage('DEBUG', message, ...args)); // 使用stderr避免干扰stdout
}
}
info(message: string, ...args: any[]): void {
if (this.shouldLog(LogLevel.INFO)) {
console.error(this.formatMessage('INFO', message, ...args)); // 使用stderr避免干扰stdout
}
}
warn(message: string, ...args: any[]): void {
if (this.shouldLog(LogLevel.WARN)) {
console.error(this.formatMessage('WARN', message, ...args)); // 使用stderr避免干扰stdout
}
}
error(message: string, ...args: any[]): void {
if (this.shouldLog(LogLevel.ERROR)) {
console.error(this.formatMessage('ERROR', message, ...args)); // 使用stderr避免干扰stdout
}
}
}
export const logger = Logger.getInstance();