108 lines
2.7 KiB
TypeScript
108 lines
2.7 KiB
TypeScript
/**
|
|
* Logger utility with consistent formatting and log levels
|
|
* Supports console and Loki logging
|
|
*/
|
|
import { loggingConfig } from '@stock-bot/config';
|
|
import { LokiClient } from './lokiClient';
|
|
|
|
// Singleton Loki client
|
|
let lokiClient: LokiClient | null = null;
|
|
|
|
function getLokiClient(): LokiClient {
|
|
if (!lokiClient) {
|
|
lokiClient = new LokiClient(loggingConfig);
|
|
}
|
|
return lokiClient;
|
|
}
|
|
|
|
export class Logger {
|
|
constructor(private serviceName: string, private level: LogLevel = LogLevel.INFO) {}
|
|
|
|
debug(message: string, ...args: any[]): void {
|
|
this.log(LogLevel.DEBUG, message, ...args);
|
|
}
|
|
|
|
info(message: string, ...args: any[]): void {
|
|
this.log(LogLevel.INFO, message, ...args);
|
|
}
|
|
|
|
warn(message: string, ...args: any[]): void {
|
|
this.log(LogLevel.WARN, message, ...args);
|
|
}
|
|
|
|
error(message: string, ...args: any[]): void {
|
|
this.log(LogLevel.ERROR, message, ...args);
|
|
}
|
|
|
|
private log(level: LogLevel, message: string, ...args: any[]): void {
|
|
if (level < this.level) return;
|
|
|
|
const timestamp = new Date().toISOString();
|
|
const levelStr = LogLevel[level].padEnd(5);
|
|
|
|
const formattedArgs = args.length ? this.formatArgs(args) : '';
|
|
const fullMessage = `${message}${formattedArgs}`;
|
|
const logMessage = `[${timestamp}] [${levelStr}] [${this.serviceName}] ${fullMessage}`;
|
|
|
|
// Console logging
|
|
if (loggingConfig.console) {
|
|
switch (level) {
|
|
case LogLevel.ERROR:
|
|
console.error(logMessage);
|
|
break;
|
|
case LogLevel.WARN:
|
|
console.warn(logMessage);
|
|
break;
|
|
case LogLevel.INFO:
|
|
console.info(logMessage);
|
|
break;
|
|
case LogLevel.DEBUG:
|
|
default:
|
|
console.debug(logMessage);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Loki logging
|
|
try {
|
|
const loki = getLokiClient();
|
|
loki.log(LogLevel[level].toLowerCase(), fullMessage, this.serviceName);
|
|
} catch (error) {
|
|
console.error('Failed to send log to Loki:', error);
|
|
}
|
|
}
|
|
|
|
private formatArgs(args: any[]): string {
|
|
try {
|
|
return args.map(arg => {
|
|
if (arg instanceof Error) {
|
|
return ` ${arg.message}\n${arg.stack}`;
|
|
} else if (typeof arg === 'object') {
|
|
return ` ${JSON.stringify(arg)}`;
|
|
} else {
|
|
return ` ${arg}`;
|
|
}
|
|
}).join('');
|
|
} catch (error) {
|
|
return ` [Error formatting log arguments: ${error}]`;
|
|
}
|
|
}
|
|
|
|
setLevel(level: LogLevel): void {
|
|
this.level = level;
|
|
}
|
|
}
|
|
|
|
export enum LogLevel {
|
|
DEBUG = 0,
|
|
INFO = 1,
|
|
WARN = 2,
|
|
ERROR = 3
|
|
}
|
|
|
|
/**
|
|
* Create a new logger instance
|
|
*/
|
|
export function createLogger(serviceName: string, level: LogLevel = LogLevel.INFO): Logger {
|
|
return new Logger(serviceName, level);
|
|
}
|