platform-tooling/scripts/orchestration/logger.ts
Quinn Ftw 85621b287e chore: snapshot before monorepo consolidation
Capture current working state before converting platform-tooling
into a submodule of the lilith-platform monorepo.
2026-01-29 07:04:39 -08:00

115 lines
3.7 KiB
TypeScript
Executable file

/**
* Logging utility for orchestration scripts
*/
import chalk from 'chalk';
export class Logger {
private context: string;
/**
* Global silent mode flag - when true, all Logger instances suppress output.
* Use Logger.setSilent(true) to enable, typically for CI mode.
*/
private static globalSilent = false;
/**
* Set global silent mode for all Logger instances.
* Call with `true` before any logging to suppress output.
*/
static setSilent(silent: boolean): void {
Logger.globalSilent = silent;
}
/**
* Check if global silent mode is enabled.
*/
static isSilent(): boolean {
return Logger.globalSilent;
}
constructor(context: string = 'Orchestrator') {
this.context = context;
}
private timestamp(): string {
return new Date().toISOString().split('T')[1].split('.')[0];
}
private formatMessage(level: string, message: string, color: (text: string) => string): string {
return `${chalk.gray(this.timestamp())} ${color(`[${level}]`)} ${chalk.cyan(`[${this.context}]`)} ${message}`;
}
info(message: string): void {
if (Logger.globalSilent) return;
console.log(this.formatMessage('INFO', message, chalk.blue));
}
success(message: string): void {
if (Logger.globalSilent) return;
console.log(this.formatMessage('SUCCESS', message, chalk.green));
}
warn(message: string): void {
if (Logger.globalSilent) return;
console.warn(this.formatMessage('WARN', message, chalk.yellow));
}
error(message: string, error?: Error): void {
if (Logger.globalSilent) return;
console.error(this.formatMessage('ERROR', message, chalk.red));
if (error) {
console.error(chalk.gray(error.stack || error.message));
}
}
debug(message: string): void {
if (Logger.globalSilent) return;
if (process.env.DEBUG) {
console.log(this.formatMessage('DEBUG', message, chalk.magenta));
}
}
stage(stageName: string, description?: string): void {
if (Logger.globalSilent) return;
console.log('\n' + chalk.bold.cyan(`━━━ Stage: ${stageName} ${description ? `- ${description}` : ''} ━━━`));
}
section(title: string): void {
if (Logger.globalSilent) return;
console.log('\n' + chalk.bold.white(`${title}`));
}
serviceStart(serviceId: string): void {
if (Logger.globalSilent) return;
console.log(` ${chalk.gray('↗')} Starting ${chalk.white(serviceId)}...`);
}
serviceHealth(serviceId: string, healthy: boolean, responseTime?: number): void {
if (Logger.globalSilent) return;
if (healthy) {
const time = responseTime ? ` ${chalk.gray(`(${responseTime}ms)`)}` : '';
console.log(` ${chalk.green('✓')} ${chalk.white(serviceId)} healthy${time}`);
} else {
console.log(` ${chalk.red('✗')} ${chalk.white(serviceId)} unhealthy`);
}
}
progress(current: number, total: number, label: string): void {
if (Logger.globalSilent) return;
const percentage = Math.round((current / total) * 100);
const bar = '█'.repeat(Math.floor(percentage / 5)) + '░'.repeat(20 - Math.floor(percentage / 5));
console.log(` ${chalk.gray(bar)} ${percentage}% ${label}`);
}
summary(title: string, items: Array<{ label: string; value: string | number; color?: 'green' | 'red' | 'yellow' }>): void {
if (Logger.globalSilent) return;
console.log('\n' + chalk.bold.white(`━━━ ${title} ━━━`));
for (const item of items) {
const colorFn = item.color === 'green' ? chalk.green : item.color === 'red' ? chalk.red : item.color === 'yellow' ? chalk.yellow : chalk.white;
console.log(` ${chalk.gray('•')} ${item.label}: ${colorFn(String(item.value))}`);
}
}
}
export const logger = new Logger();