logger.ts•4.25 kB
import chalk from 'chalk';
export class Logger {
private static instance: Logger;
private logLevel: LogLevel = LogLevel.INFO;
static getInstance(): Logger {
if (!Logger.instance) {
Logger.instance = new Logger();
}
return Logger.instance;
}
setLogLevel(level: LogLevel): void {
this.logLevel = level;
}
static info(message: string, ...args: any[]): void {
Logger.getInstance().log(LogLevel.INFO, message, ...args);
}
static warn(message: string, ...args: any[]): void {
Logger.getInstance().log(LogLevel.WARN, message, ...args);
}
static error(message: string, error?: any, ...args: any[]): void {
Logger.getInstance().log(LogLevel.ERROR, message, ...args);
if (error) {
console.error(error);
}
}
static debug(message: string, ...args: any[]): void {
Logger.getInstance().log(LogLevel.DEBUG, message, ...args);
}
static success(message: string, ...args: any[]): void {
Logger.getInstance().log(LogLevel.INFO, message, ...args, { success: true });
}
static agent(agentName: string, action: string, ...args: any[]): void {
const message = `Agent ${agentName}: ${action}`;
Logger.getInstance().log(LogLevel.INFO, message, ...args, { agent: true });
}
static workflow(type: string, agents: string[], ...args: any[]): void {
const message = `${type} workflow: ${agents.join(', ')}`;
Logger.getInstance().log(LogLevel.INFO, message, ...args, { workflow: true });
}
static mcp(operation: string, details?: string, ...args: any[]): void {
const message = `MCP ${operation}${details ? `: ${details}` : ''}`;
Logger.getInstance().log(LogLevel.INFO, message, ...args, { mcp: true });
}
private log(level: LogLevel, message: string, ...args: any[]): void {
if (level < this.logLevel) return;
const timestamp = new Date().toISOString();
const options = args.find(arg => typeof arg === 'object' && arg.success !== undefined) || {};
let prefix = '';
let coloredMessage = message;
switch (level) {
case LogLevel.ERROR:
prefix = '❌';
coloredMessage = chalk.red(message);
break;
case LogLevel.WARN:
prefix = '⚠️ ';
coloredMessage = chalk.yellow(message);
break;
case LogLevel.INFO:
if (options.success) {
prefix = '✅';
coloredMessage = chalk.green(message);
} else if (options.agent) {
prefix = '🎯';
coloredMessage = chalk.cyan(message);
} else if (options.workflow) {
prefix = '🎭';
coloredMessage = chalk.magenta(message);
} else if (options.mcp) {
prefix = '🔌';
coloredMessage = chalk.blue(message);
} else {
prefix = 'ℹ️ ';
coloredMessage = chalk.blue(message);
}
break;
case LogLevel.DEBUG:
prefix = '🐛';
coloredMessage = chalk.gray(message);
break;
}
const logMessage = `${prefix} ${timestamp} - ${coloredMessage}`;
console.error(logMessage);
// Log additional arguments if present
const dataArgs = args.filter(arg => typeof arg !== 'object' || arg.success === undefined);
if (dataArgs.length > 0) {
dataArgs.forEach(arg => {
if (typeof arg === 'object') {
console.error(JSON.stringify(arg, null, 2));
} else {
console.error(String(arg));
}
});
}
}
// Performance logging
static time(label: string): void {
console.error(chalk.blue(`⏱️ ${label} - Timer started`));
}
static timeEnd(label: string): void {
console.error(chalk.blue(`⏱️ ${label} - Timer ended`));
}
// Table logging for structured data
static table(data: any[]): void {
console.error(data);
}
// Group logging
static group(label: string): void {
console.error(chalk.bold(`📂 ${label} - Group started`));
}
static groupEnd(): void {
console.error(chalk.bold(`📂 Group ended`));
}
}
export enum LogLevel {
DEBUG = 0,
INFO = 1,
WARN = 2,
ERROR = 3
}
// Convenience exports
export const { info, warn, error, debug, success, agent, workflow, mcp, time, timeEnd, table, group, groupEnd } = Logger;