Clarify stored run log naming

This commit is contained in:
Matt Isenhower
2026-09-07 17:29:45 -07:00
parent 706b7ee0e8
commit 489e471e3c

View File

@@ -1,37 +1,39 @@
import { AsyncLocalStorage } from 'node:async_hooks';
// Associate messages with their run across awaits, without replacing the global console.
const currentRun = new AsyncLocalStorage();
const MAX_LINES = 200;
const MAX_LINE_LENGTH = 500;
const MAX_BYTES = 32_000;
const currentRunLog = new AsyncLocalStorage();
// Limits for retained admin-panel logs; console output is unaffected.
const MAX_STORED_LINES = 200;
const MAX_STORED_LINE_LENGTH = 500;
const MAX_STORED_BYTES = 32_000;
const encoder = new TextEncoder();
// The admin panel reads snapshot during the run and saves it with the final result.
export class RunLog {
constructor(secrets = []) {
this.snapshot = { lines: [], omitted: 0 };
this.bytes = 0;
this.storedBytes = 0;
this.secrets = secrets.filter(value => typeof value === 'string' && value.length >= 6);
}
run(callback) {
return currentRun.run(this, callback);
return currentRunLog.run(this, callback);
}
append(level, message, fields) {
let line = { at: Date.now(), level, text: this.formatMessage(message, fields) };
let line = { at: Date.now(), level, text: this.formatStoredMessage(message, fields) };
this.snapshot.lines.push(line);
this.bytes += this.lineSize(line);
this.storedBytes += this.storedLineBytes(line);
while (this.snapshot.lines.length > MAX_LINES || this.bytes > MAX_BYTES) {
while (this.snapshot.lines.length > MAX_STORED_LINES || this.storedBytes > MAX_STORED_BYTES) {
let removed = this.snapshot.lines.shift();
this.bytes -= this.lineSize(removed);
this.storedBytes -= this.storedLineBytes(removed);
this.snapshot.omitted++;
}
}
formatMessage(message, fields) {
formatStoredMessage(message, fields) {
let text = message instanceof Error ? message.message : String(message);
// Keep readable progress messages; the full structured result has its own JSON view.
@@ -46,12 +48,12 @@ export class RunLog {
text = text.replaceAll(secret, '[redacted]');
text = text.replace(/Bearer\s+[^\s,;]+/gi, 'Bearer [redacted]');
if (text.length > MAX_LINE_LENGTH)
text = text.slice(0, MAX_LINE_LENGTH) + '…';
if (text.length > MAX_STORED_LINE_LENGTH)
text = text.slice(0, MAX_STORED_LINE_LENGTH) + '…';
return text;
}
lineSize(line) {
storedLineBytes(line) {
return encoder.encode(JSON.stringify(line)).length;
}
}
@@ -65,7 +67,7 @@ export function logMessage(level, message, fields) {
console[level](message, fields);
}
let run = currentRun.getStore();
if (run)
run.append(level, message, fields);
let runLog = currentRunLog.getStore();
if (runLog)
runLog.append(level, message, fields);
}