claude-flow-multilang
Version:
Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture
139 lines (115 loc) • 3.96 kB
text/typescript
import * as process from 'node:process';
/**
* Migration Logger - Structured logging for migration operations
*/
import * as fs from 'fs-extra';
import * as path from 'path';
import * as chalk from 'chalk';
export interface LogEntry {
timestamp: Date;
level: 'info' | 'warn' | 'error' | 'success' | 'debug';
message: string;
context?: any;
stack?: string;
}
export class MigrationLogger {
private logFile?: string;
private entries: LogEntry[] = [];
constructor(logFile?: string) {
this.logFile = logFile;
}
info(message: string, context?: any): void {
this.log('info', message, context);
console.log(chalk.blue(`ℹ️ ${message}`));
}
warn(message: string, context?: any): void {
this.log('warn', message, context);
console.log(chalk.yellow(`⚠️ ${message}`));
}
error(message: string, error?: Error | any, context?: any): void {
this.log('error', message, context, error?.stack);
console.log(chalk.red(`❌ ${message}`));
if (error && (error instanceof Error ? error.message : String(error)) !== message) {
console.log(chalk.red(` ${error instanceof Error ? error.message : String(error)}`));
}
}
success(message: string, context?: any): void {
this.log('success', message, context);
console.log(chalk.green(`✅ ${message}`));
}
debug(message: string, context?: any): void {
if (process.env.DEBUG === 'true' || process.env.NODE_ENV === 'development') {
this.log('debug', message, context);
console.log(chalk.gray(`🔍 ${message}`));
}
}
private log(level: LogEntry['level'], message: string, context?: any, stack?: string): void {
const entry: LogEntry = {
timestamp: new Date(),
level,
message,
context,
stack,
};
this.entries.push(entry);
if (this.logFile) {
this.writeToFile(entry);
}
}
private async writeToFile(entry: LogEntry): Promise<void> {
if (!this.logFile) return;
try {
const logDir = path.dirname(this.logFile);
await fs.ensureDir(logDir);
const logLine = JSON.stringify(entry) + '\n';
await fs.appendFile(this.logFile, logLine);
} catch (error) {
// Prevent recursive logging
console.error(
'Failed to write to log file:',
error instanceof Error ? error.message : String(error),
);
}
}
async saveToFile(filePath: string): Promise<void> {
await fs.ensureDir(path.dirname(filePath));
await fs.writeJson(filePath, this.entries, { spaces: 2 });
}
getEntries(): LogEntry[] {
return [...this.entries];
}
getEntriesByLevel(level: LogEntry['level']): LogEntry[] {
return this.entries.filter((entry) => entry.level === level);
}
clear(): void {
this.entries = [];
}
printSummary(): void {
const summary = {
total: this.entries.length,
info: this.getEntriesByLevel('info').length,
warn: this.getEntriesByLevel('warn').length,
error: this.getEntriesByLevel('error').length,
success: this.getEntriesByLevel('success').length,
debug: this.getEntriesByLevel('debug').length,
};
console.log(chalk.bold('\n📊 Migration Log Summary'));
console.log(chalk.gray('─'.repeat(30)));
console.log(`Total entries: ${summary.total}`);
console.log(`${chalk.blue('Info:')} ${summary.info}`);
console.log(`${chalk.green('Success:')} ${summary.success}`);
console.log(`${chalk.yellow('Warnings:')} ${summary.warn}`);
console.log(`${chalk.red('Errors:')} ${summary.error}`);
if (summary.debug > 0) {
console.log(`${chalk.gray('Debug:')} ${summary.debug}`);
}
console.log(chalk.gray('─'.repeat(30)));
}
}
// Global logger instance
export const logger = new MigrationLogger();
// Set log file if in production
if (process.env.NODE_ENV === 'production') {
const logFile = path.join(process.cwd(), 'logs', 'migration.log');
logger['logFile'] = logFile;
}