RPC: route logs to stderr to keep stdout JSON clean

This commit is contained in:
Peter Steinberger
2025-12-09 04:30:22 +00:00
parent 998a5b080d
commit d66a05dc41
2 changed files with 20 additions and 1 deletions

View File

@@ -44,6 +44,7 @@ let cachedLogger: TsLogger<LogObj> | null = null;
let cachedSettings: ResolvedSettings | null = null;
let overrideSettings: LoggerSettings | null = null;
let consolePatched = false;
let forceConsoleToStderr = false;
function normalizeLevel(level?: string): Level {
if (isVerbose()) return "trace";
@@ -183,6 +184,12 @@ export function resetLogger() {
overrideSettings = null;
}
// Route all console output (including tslog console writes) to stderr.
// This keeps stdout clean for RPC/JSON modes.
export function routeLogsToStderr(): void {
forceConsoleToStderr = true;
}
/**
* Route console.* calls through pino while still emitting to stdout/stderr.
* This keeps user-facing output unchanged but guarantees every console call is captured in log files.
@@ -224,7 +231,15 @@ export function enableConsoleCapture(): void {
} catch {
// never block console output on logging failures
}
orig.apply(console, args as []);
if (forceConsoleToStderr) {
const target =
level === "error" || level === "fatal" || level === "warn"
? process.stderr
: process.stderr; // in RPC/JSON mode, keep stdout clean
target.write(`${formatted}\n`);
} else {
orig.apply(console, args as []);
}
};
console.log = forward("info", original.log);

View File

@@ -15,6 +15,7 @@ import {
listSystemPresence,
updateSystemPresence,
} from "../infra/system-presence.js";
import { routeLogsToStderr } from "../logging.js";
import { setHeartbeatsEnabled } from "../provider-web.js";
import type { RuntimeEnv } from "../runtime.js";
@@ -28,6 +29,9 @@ export async function runRpcLoop(io: {
input: Readable;
output: Writable;
}): Promise<RpcLoopHandles> {
// Keep stdout reserved for RPC JSON replies; send all other logs to stderr.
routeLogsToStderr();
const rl = createInterface({ input: io.input, crlfDelay: Infinity });
const respond = (obj: unknown) => {