export enum LogLevel {
DEBUG = "DEBUG",
INFO = "INFO",
WARN = "WARN",
ERROR = "ERROR",
}
export interface LogMeta {
[key: string]: any;
}
export class Logger {
private static instance: Logger;
private constructor() {}
static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
log(level: LogLevel, message: string, meta?: LogMeta): void {
const timestamp = new Date().toISOString();
const logEntry = {
timestamp,
level,
message,
...meta,
};
// Log to console with appropriate level
switch (level) {
case LogLevel.ERROR:
console.error(JSON.stringify(logEntry));
break;
case LogLevel.WARN:
console.warn(JSON.stringify(logEntry));
break;
case LogLevel.INFO:
console.info(JSON.stringify(logEntry));
break;
case LogLevel.DEBUG:
console.debug(JSON.stringify(logEntry));
break;
}
}
debug(message: string, meta?: LogMeta): void {
this.log(LogLevel.DEBUG, message, meta);
}
info(message: string, meta?: LogMeta): void {
this.log(LogLevel.INFO, message, meta);
}
warn(message: string, meta?: LogMeta): void {
this.log(LogLevel.WARN, message, meta);
}
error(message: string, meta?: LogMeta): void {
this.log(LogLevel.ERROR, message, meta);
}
}