fix(scripts): bound gateway watch log capture

This commit is contained in:
Vincent Koc
2026-05-28 08:45:18 +02:00
parent 00fb15253c
commit 0ade360da5
2 changed files with 75 additions and 13 deletions

View File

@@ -42,6 +42,33 @@ const WATCH_GATEWAY_SKIP_ENV = {
NODE_ENV: "test",
};
export const WATCH_LOG_CAPTURE_MAX_CHARS = 2 * 1024 * 1024;
const WATCH_BUILD_DETECTION_MAX_CHARS = 4096;
export function appendBoundedWatchLog(current, chunk, maxChars = WATCH_LOG_CAPTURE_MAX_CHARS) {
const next = `${current}${String(chunk)}`;
if (next.length <= maxChars) {
return { text: next, truncated: false };
}
return { text: next.slice(-maxChars), truncated: true };
}
function formatCapturedWatchLog(text, truncated) {
return truncated ? `[openclaw] log truncated to last ${WATCH_LOG_CAPTURE_MAX_CHARS} chars\n${text}` : text;
}
export function updateWatchBuildDetection(state, chunk) {
const combined = `${state.buffer ?? ""}${String(chunk)}`;
const next = appendBoundedWatchLog("", combined, WATCH_BUILD_DETECTION_MAX_CHARS);
const reason = detectWatchBuildReason(combined, "");
const triggered = state.triggered || combined.includes("Building TypeScript (dist is stale");
return {
buffer: next.text,
triggered,
reason: state.reason ?? reason,
};
}
function parseArgs(argv) {
const options = { ...DEFAULTS };
for (let i = 0; i < argv.length; i += 1) {
@@ -464,11 +491,20 @@ async function runTimedWatch(options, outputDir) {
let stdout = "";
let stderr = "";
let stdoutTruncated = false;
let stderrTruncated = false;
let buildDetection = { buffer: "", triggered: false, reason: null };
child.stdout?.on("data", (chunk) => {
stdout += String(chunk);
const next = appendBoundedWatchLog(stdout, chunk);
stdout = next.text;
stdoutTruncated ||= next.truncated;
buildDetection = updateWatchBuildDetection(buildDetection, chunk);
});
child.stderr?.on("data", (chunk) => {
stderr += String(chunk);
const next = appendBoundedWatchLog(stderr, chunk);
stderr = next.text;
stderrTruncated ||= next.truncated;
buildDetection = updateWatchBuildDetection(buildDetection, chunk);
});
let watchPid = null;
@@ -492,8 +528,8 @@ async function runTimedWatch(options, outputDir) {
const idleCpuEndMs = watchPid ? readProcessTreeCpuMs(watchPid) : null;
const exit = await stopTimedWatchChild(child, watchPid, options);
fs.writeFileSync(stdoutPath, stdout, "utf8");
fs.writeFileSync(stderrPath, stderr, "utf8");
fs.writeFileSync(stdoutPath, formatCapturedWatchLog(stdout, stdoutTruncated), "utf8");
fs.writeFileSync(stderrPath, formatCapturedWatchLog(stderr, stderrTruncated), "utf8");
const timing = fs.existsSync(timeFilePath)
? parseTimingFile(timeFilePath)
: { userSeconds: Number.NaN, sysSeconds: Number.NaN, elapsedSeconds: Number.NaN };
@@ -509,6 +545,8 @@ async function runTimedWatch(options, outputDir) {
stdoutPath,
stderrPath,
timeFilePath,
watchTriggeredBuild: buildDetection.triggered,
watchBuildReason: buildDetection.reason,
};
}
@@ -706,15 +744,8 @@ async function main() {
(watchResult.timing.userSeconds + watchResult.timing.sysSeconds) * 1000,
);
const cpuMs = watchResult.idleCpuMs ?? totalCpuMs;
const watchTriggeredBuild =
fs
.readFileSync(watchResult.stderrPath, "utf8")
.includes("Building TypeScript (dist is stale") ||
fs.readFileSync(watchResult.stdoutPath, "utf8").includes("Building TypeScript (dist is stale");
const watchBuildReason = detectWatchBuildReason(
fs.readFileSync(watchResult.stdoutPath, "utf8"),
fs.readFileSync(watchResult.stderrPath, "utf8"),
);
const watchTriggeredBuild = watchResult.watchTriggeredBuild;
const watchBuildReason = watchResult.watchBuildReason;
const summary = {
windowMs: options.windowMs,