diff --git a/docs/logging.md b/docs/logging.md index 3466a8836..c8fc987e7 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -76,6 +76,7 @@ Behavior: - **Subsystem prefixes** on every line (e.g. `[gateway]`, `[canvas]`, `[tailscale]`) - **Subsystem colors** (stable per subsystem) plus level coloring - **Color when output is a TTY or the environment looks like a rich terminal** (`TERM`/`COLORTERM`/`TERM_PROGRAM`), respects `NO_COLOR` +- **Shortened subsystem prefixes**: drops leading `gateway/` + `providers/`, keeps last 2 segments (e.g. `whatsapp/outbound`) - **Sub-loggers by subsystem** (auto prefix + structured field `{ subsystem }`) - **`logRaw()`** for QR/UX output (no prefix, no formatting) - **Console styles** (e.g. `pretty | compact | json`) diff --git a/src/logging.ts b/src/logging.ts index c00428102..c94d25919 100644 --- a/src/logging.ts +++ b/src/logging.ts @@ -370,6 +370,8 @@ const SUBSYSTEM_COLORS = [ "magenta", "red", ] as const; +const SUBSYSTEM_PREFIXES_TO_DROP = ["gateway", "providers"] as const; +const SUBSYSTEM_MAX_SEGMENTS = 2; function pickSubsystemColor( color: ChalkInstance, @@ -384,6 +386,24 @@ function pickSubsystemColor( return color[name]; } +function formatSubsystemForConsole(subsystem: string): string { + const parts = subsystem.split("/").filter(Boolean); + const original = parts.join("/") || subsystem; + while ( + parts.length > 0 && + SUBSYSTEM_PREFIXES_TO_DROP.includes( + parts[0] as (typeof SUBSYSTEM_PREFIXES_TO_DROP)[number], + ) + ) { + parts.shift(); + } + if (parts.length === 0) return original; + if (parts.length > SUBSYSTEM_MAX_SEGMENTS) { + return parts.slice(-SUBSYSTEM_MAX_SEGMENTS).join("/"); + } + return parts.join("/"); +} + function formatConsoleLine(opts: { level: Level; subsystem: string; @@ -391,18 +411,22 @@ function formatConsoleLine(opts: { style: ConsoleStyle; meta?: Record; }): string { + const displaySubsystem = + opts.style === "json" + ? opts.subsystem + : formatSubsystemForConsole(opts.subsystem); if (opts.style === "json") { return JSON.stringify({ time: new Date().toISOString(), level: opts.level, - subsystem: opts.subsystem, + subsystem: displaySubsystem, message: opts.message, ...opts.meta, }); } const color = getColorForConsole(); - const prefix = `[${opts.subsystem}]`; - const prefixColor = pickSubsystemColor(color, opts.subsystem); + const prefix = `[${displaySubsystem}]`; + const prefixColor = pickSubsystemColor(color, displaySubsystem); const levelColor = opts.level === "error" || opts.level === "fatal" ? color.red