121 lines
2.9 KiB
TypeScript
121 lines
2.9 KiB
TypeScript
/**
|
|
* Logging utilities for GitOps
|
|
*/
|
|
|
|
import type { ISyncLogEntry } from '../ts_interfaces/data/sync.ts';
|
|
|
|
type LogLevel = 'info' | 'success' | 'warn' | 'error' | 'debug';
|
|
|
|
const SYNC_LOG_MAX = 500;
|
|
|
|
class Logger {
|
|
private debugMode = false;
|
|
private syncLogBuffer: ISyncLogEntry[] = [];
|
|
private broadcastFn?: (entry: ISyncLogEntry) => void;
|
|
|
|
constructor() {
|
|
this.debugMode = Deno.args.includes('--debug') || Deno.env.get('DEBUG') === 'true';
|
|
}
|
|
|
|
/**
|
|
* Set the broadcast function used to push sync log entries to connected clients.
|
|
*/
|
|
setBroadcastFn(fn: (entry: ISyncLogEntry) => void): void {
|
|
this.broadcastFn = fn;
|
|
}
|
|
|
|
/**
|
|
* Log a sync-related message to both the console and the ring buffer.
|
|
* Also broadcasts to connected frontends via TypedSocket if available.
|
|
*/
|
|
syncLog(level: ISyncLogEntry['level'], message: string, source?: string): void {
|
|
// Also log to console
|
|
this.log(level, message);
|
|
|
|
const entry: ISyncLogEntry = {
|
|
timestamp: Date.now(),
|
|
level,
|
|
message,
|
|
source,
|
|
};
|
|
|
|
this.syncLogBuffer.push(entry);
|
|
if (this.syncLogBuffer.length > SYNC_LOG_MAX) {
|
|
this.syncLogBuffer.splice(0, this.syncLogBuffer.length - SYNC_LOG_MAX);
|
|
}
|
|
|
|
if (this.broadcastFn) {
|
|
this.broadcastFn(entry);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get recent sync log entries.
|
|
*/
|
|
getSyncLogs(limit = 100): ISyncLogEntry[] {
|
|
return this.syncLogBuffer.slice(-limit);
|
|
}
|
|
|
|
log(level: LogLevel, message: string, ...args: unknown[]): void {
|
|
const prefix = this.getPrefix(level);
|
|
const formattedMessage = `${prefix} ${message}`;
|
|
|
|
switch (level) {
|
|
case 'error':
|
|
console.error(formattedMessage, ...args);
|
|
break;
|
|
case 'warn':
|
|
console.warn(formattedMessage, ...args);
|
|
break;
|
|
case 'debug':
|
|
if (this.debugMode) {
|
|
console.log(formattedMessage, ...args);
|
|
}
|
|
break;
|
|
default:
|
|
console.log(formattedMessage, ...args);
|
|
}
|
|
}
|
|
|
|
info(message: string, ...args: unknown[]): void {
|
|
this.log('info', message, ...args);
|
|
}
|
|
|
|
success(message: string, ...args: unknown[]): void {
|
|
this.log('success', message, ...args);
|
|
}
|
|
|
|
warn(message: string, ...args: unknown[]): void {
|
|
this.log('warn', message, ...args);
|
|
}
|
|
|
|
error(message: string, ...args: unknown[]): void {
|
|
this.log('error', message, ...args);
|
|
}
|
|
|
|
debug(message: string, ...args: unknown[]): void {
|
|
this.log('debug', message, ...args);
|
|
}
|
|
|
|
private getPrefix(level: LogLevel): string {
|
|
const colors: Record<LogLevel, string> = {
|
|
info: '\x1b[36m',
|
|
success: '\x1b[32m',
|
|
warn: '\x1b[33m',
|
|
error: '\x1b[31m',
|
|
debug: '\x1b[90m',
|
|
};
|
|
const reset = '\x1b[0m';
|
|
const icons: Record<LogLevel, string> = {
|
|
info: 'i',
|
|
success: '+',
|
|
warn: '!',
|
|
error: 'x',
|
|
debug: '*',
|
|
};
|
|
return `${colors[level]}[${icons[level]}]${reset}`;
|
|
}
|
|
}
|
|
|
|
export const logger = new Logger();
|