mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-07-28 04:38:59 +00:00
e876a91a2e
Config changes (eslint.config.mjs): - no-unused-vars: caughtErrors=none (catch clause vars are intentionally ignored throughout) - varsIgnorePattern/argsIgnorePattern: ^_ (allow _-prefixed intentional ignores) - ban-ts-comment, no-namespace, no-empty: downgraded to warn (pre-existing patterns) - no-control-regex: off (terminal output processing intentionally uses control chars) Dead code removed: - index.ts: remove unused spawn/exec/promisify imports and dead execAsync variable - FileSystemService.ts: remove duplicate fs default import (fsPromises already imported) - LogFormatter.ts: remove unused parsed variable (JSON.parse used only for validation) Auto-fixed via eslint --fix: - prefer-const: ComposeService, DockerController, MonitorService, index.ts
88 lines
3.8 KiB
TypeScript
88 lines
3.8 KiB
TypeScript
export class LogFormatter {
|
|
// ANSI Color Codes
|
|
private static readonly GRAY = '\x1b[90m';
|
|
private static readonly CYAN = '\x1b[36m';
|
|
private static readonly RED = '\x1b[31m';
|
|
private static readonly YELLOW = '\x1b[33m';
|
|
private static readonly BLUE = '\x1b[34m';
|
|
private static readonly WHITE = '\x1b[37m';
|
|
private static readonly RESET = '\x1b[0m';
|
|
|
|
// Regex patterns
|
|
// Matches standard ISO timestamps like "2024-02-26T12:34:56.789Z " or "2024-02-26 12:34:56 " at the start
|
|
private static readonly TIMESTAMP_REGEX = /^(\d{4}-\d{2}-\d{2}[T\s]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?\s*)/;
|
|
|
|
// Matches docker-compose style prefix like "container-name | " or "db-1 | "
|
|
private static readonly PREFIX_REGEX = /^([a-zA-Z0-9_-]+)(?:\s+\|\s+)/;
|
|
|
|
// Level regexes (case insensitive for matching, but we check raw string for precise targeting if needed)
|
|
private static readonly ERROR_REGEX = /\b(ERROR|ERR|Exception|Fatal)\b/i;
|
|
private static readonly WARN_REGEX = /\b(WARN|WRN)\b/i;
|
|
private static readonly INFO_REGEX = /\b(INFO|INF)\b/i;
|
|
|
|
public static process(line: string): string {
|
|
if (!line || line.trim() === '') return line;
|
|
|
|
let processedLine = line;
|
|
let formatAccumulator = '';
|
|
|
|
// 1. Process Timestamp
|
|
const tsMatch = processedLine.match(LogFormatter.TIMESTAMP_REGEX);
|
|
if (tsMatch) {
|
|
const ts = tsMatch[1];
|
|
formatAccumulator += `${LogFormatter.GRAY}${ts}${LogFormatter.RESET}`;
|
|
processedLine = processedLine.slice(ts.length);
|
|
}
|
|
|
|
// 2. Process Prefix
|
|
const prefixMatch = processedLine.match(LogFormatter.PREFIX_REGEX);
|
|
if (prefixMatch) {
|
|
const pfxMatchStr = prefixMatch[0]; // e.g. "container-name | "
|
|
const name = prefixMatch[1];
|
|
const restOfPrefix = pfxMatchStr.slice(name.length); // e.g. " | "
|
|
|
|
formatAccumulator += `${LogFormatter.CYAN}${name}${LogFormatter.WHITE}${LogFormatter.RESET}${restOfPrefix}`;
|
|
processedLine = processedLine.slice(pfxMatchStr.length);
|
|
}
|
|
|
|
// 3. Process Levels & JSON
|
|
const trimmedLine = processedLine.trim();
|
|
|
|
// Fast JSON Check (Starts with { and ends with })
|
|
if (trimmedLine.startsWith('{') && trimmedLine.endsWith('}')) {
|
|
try {
|
|
JSON.parse(trimmedLine);
|
|
// If valid, lightly highlight it (e.g., colorize string representation slightly)
|
|
// We re-stringify it to ensure it's on one line, but maybe just highlight properties
|
|
processedLine = LogFormatter.highlightJson(trimmedLine);
|
|
} catch (e) {
|
|
// Not valid JSON, fall through to level checking
|
|
processedLine = LogFormatter.highlightLevels(processedLine);
|
|
}
|
|
} else {
|
|
// 4. Highlight Levels (Error, Warn, etc.)
|
|
processedLine = LogFormatter.highlightLevels(processedLine);
|
|
}
|
|
|
|
return formatAccumulator + processedLine;
|
|
}
|
|
|
|
private static highlightLevels(text: string): string {
|
|
if (LogFormatter.ERROR_REGEX.test(text)) {
|
|
return `${LogFormatter.RED}${text}${LogFormatter.RESET}`;
|
|
}
|
|
if (LogFormatter.WARN_REGEX.test(text)) {
|
|
return `${LogFormatter.YELLOW}${text}${LogFormatter.RESET}`;
|
|
}
|
|
// For INFO, we can leave as default, or we can make the whole line a bit brighter, but let's leave default to avoid washing out the terminal
|
|
return text;
|
|
}
|
|
|
|
private static highlightJson(jsonStr: string): string {
|
|
// A simple regex to highlight JSON keys in blue
|
|
// Matches "key":
|
|
const keyRegex = /"([^"]+)":/g;
|
|
return jsonStr.replace(keyRegex, `${LogFormatter.BLUE}"$1"${LogFormatter.RESET}:`);
|
|
}
|
|
}
|