fix: add timestamped tool context to logs

This commit is contained in:
Peter Steinberger
2026-01-17 18:14:18 +00:00
parent 1569d29b2d
commit 5304a8c2d1
5 changed files with 166 additions and 4 deletions

View File

@@ -67,6 +67,10 @@ export function setConsoleSubsystemFilter(filters?: string[] | null): void {
loggingState.consoleSubsystemFilter = normalized.length > 0 ? normalized : null;
}
export function setConsoleTimestampPrefix(enabled: boolean): void {
loggingState.consoleTimestampPrefix = enabled;
}
export function shouldLogSubsystemToConsole(subsystem: string): boolean {
const filter = loggingState.consoleSubsystemFilter;
if (!filter || filter.length === 0) {
@@ -93,6 +97,33 @@ function isEpipeError(err: unknown): boolean {
return code === "EPIPE" || code === "EIO";
}
function formatConsoleTimestamp(style: ConsoleStyle): string {
const now = new Date().toISOString();
if (style === "pretty") return now.slice(11, 19);
return now;
}
function hasTimestampPrefix(value: string): boolean {
return /^(?:\d{2}:\d{2}:\d{2}|\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?)/.test(
value,
);
}
function isJsonPayload(value: string): boolean {
const trimmed = value.trim();
if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return false;
try {
JSON.parse(trimmed);
return true;
} catch {
return false;
}
}
function stripAnsi(value: string): string {
return value.replace(/\u001b\[[0-9;]*m/g, "");
}
/**
* Route console.* calls through file logging while still emitting to stdout/stderr.
* This keeps user-facing output unchanged but guarantees every console call is captured in log files.
@@ -123,6 +154,15 @@ export function enableConsoleCapture(): void {
(...args: unknown[]) => {
const formatted = util.format(...args);
if (shouldSuppressConsoleMessage(formatted)) return;
const trimmed = stripAnsi(formatted).trimStart();
const shouldPrefixTimestamp =
loggingState.consoleTimestampPrefix &&
trimmed.length > 0 &&
!hasTimestampPrefix(trimmed) &&
!isJsonPayload(trimmed);
const timestamp = shouldPrefixTimestamp
? formatConsoleTimestamp(getConsoleSettings().style)
: "";
try {
// Map console levels to file logger
if (level === "trace") {
@@ -144,14 +184,27 @@ export function enableConsoleCapture(): void {
if (loggingState.forceConsoleToStderr) {
// in RPC/JSON mode, keep stdout clean
try {
process.stderr.write(`${formatted}\n`);
const line = timestamp ? `${timestamp} ${formatted}` : formatted;
process.stderr.write(`${line}\n`);
} catch (err) {
if (isEpipeError(err)) return;
throw err;
}
} else {
try {
orig.apply(console, args as []);
if (!timestamp) {
orig.apply(console, args as []);
return;
}
if (args.length === 0) {
orig.call(console, timestamp);
return;
}
if (typeof args[0] === "string") {
orig.call(console, `${timestamp} ${args[0]}`, ...args.slice(1));
return;
}
orig.call(console, timestamp, ...args);
} catch (err) {
if (isEpipeError(err)) return;
throw err;