mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(dev): bound anthropic prompt log tails
This commit is contained in:
@@ -67,6 +67,7 @@ const CAPTURE_PROXY_MAX_BODY_BYTES = parseStrictIntegerOption({
|
||||
min: 1,
|
||||
raw: process.env.OPENCLAW_PROMPT_CAPTURE_MAX_BODY_BYTES,
|
||||
});
|
||||
const GATEWAY_LOG_TAIL_BYTES = 256 * 1024;
|
||||
const SETUP_TOKEN_RAW = process.env.OPENCLAW_LIVE_SETUP_TOKEN?.trim() ?? "";
|
||||
const SETUP_TOKEN_VALUE = process.env.OPENCLAW_LIVE_SETUP_TOKEN_VALUE?.trim() ?? "";
|
||||
const SETUP_TOKEN_PROFILE = process.env.OPENCLAW_LIVE_SETUP_TOKEN_PROFILE?.trim() ?? "";
|
||||
@@ -626,9 +627,29 @@ async function waitForGatewayReady(url: string, token: string): Promise<void> {
|
||||
throw new Error(lastError);
|
||||
}
|
||||
|
||||
async function readLogTail(logPath: string): Promise<string> {
|
||||
const raw = await fs.readFile(logPath, "utf8").catch(() => "");
|
||||
return redactForDevToolLog(raw.split(/\r?\n/).slice(-40).join("\n").trim());
|
||||
async function readLogTail(logPath: string, maxBytes = GATEWAY_LOG_TAIL_BYTES): Promise<string> {
|
||||
if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) {
|
||||
throw new Error("maxBytes must be a positive integer");
|
||||
}
|
||||
const logFile = await fs.open(logPath, "r").catch(() => undefined);
|
||||
if (!logFile) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
const stat = await logFile.stat();
|
||||
if (stat.size <= 0) {
|
||||
return "";
|
||||
}
|
||||
const length = Math.min(stat.size, maxBytes);
|
||||
const position = Math.max(0, stat.size - length);
|
||||
const buffer = Buffer.allocUnsafe(length);
|
||||
const { bytesRead } = await logFile.read(buffer, 0, length, position);
|
||||
const raw = buffer.subarray(0, bytesRead).toString("utf8");
|
||||
const lineAlignedRaw = position > 0 ? raw.replace(/^[^\n]*(?:\r?\n|$)/u, "") : raw;
|
||||
return redactForDevToolLog(lineAlignedRaw.split(/\r?\n/).slice(-40).join("\n").trim());
|
||||
} finally {
|
||||
await logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
async function runGatewayPrompt(prompt: string): Promise<PromptResult> {
|
||||
@@ -815,6 +836,7 @@ export const testing = {
|
||||
cleanupPromptProbeTmpDir,
|
||||
matchesExtraUsage400,
|
||||
promptProbeTmpResult,
|
||||
readLogTail,
|
||||
readRequestBody,
|
||||
resolveAnthropicUpstreamUrl,
|
||||
stopGatewayPromptChild,
|
||||
|
||||
@@ -411,6 +411,41 @@ describe("script-specific dev tooling hardening", () => {
|
||||
expect(destroy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reads only the bounded Anthropic prompt probe gateway log tail", async () => {
|
||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-prompt-probe-log-"));
|
||||
tempDirs.push(tempRoot);
|
||||
const logPath = path.join(tempRoot, "gateway.log");
|
||||
const token = "sk-test1234567890abcdefghijklmnop"; // pragma: allowlist secret
|
||||
await fs.writeFile(
|
||||
logPath,
|
||||
[
|
||||
`DO_NOT_PRINT_OLD_GATEWAY_LOG OPENAI_API_KEY=${token}`,
|
||||
"x".repeat(256),
|
||||
`recent gateway tail Authorization: Bearer ${token}`,
|
||||
].join("\n"),
|
||||
"utf8",
|
||||
);
|
||||
|
||||
const tail = await promptProbeTesting.readLogTail(logPath, 128);
|
||||
|
||||
expect(tail).toContain("recent gateway tail");
|
||||
expect(tail).not.toContain("DO_NOT_PRINT_OLD_GATEWAY_LOG");
|
||||
expect(tail).not.toContain(token);
|
||||
});
|
||||
|
||||
it("drops partial Anthropic prompt probe log lines before redaction", async () => {
|
||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-prompt-probe-log-"));
|
||||
tempDirs.push(tempRoot);
|
||||
const logPath = path.join(tempRoot, "gateway.log");
|
||||
const token = `sk-test${"a".repeat(80)}`; // pragma: allowlist secret
|
||||
await fs.writeFile(logPath, `Authorization: Bearer ${token}\nrecent gateway tail`, "utf8");
|
||||
|
||||
const tail = await promptProbeTesting.readLogTail(logPath, "recent gateway tail".length + 24);
|
||||
|
||||
expect(tail).toBe("recent gateway tail");
|
||||
expect(tail).not.toContain(token.slice(-16));
|
||||
});
|
||||
|
||||
it("cleans Anthropic prompt probe temp dirs unless explicitly kept", async () => {
|
||||
const tempRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-prompt-probe-test-"));
|
||||
const keepRoot = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-prompt-probe-test-"));
|
||||
|
||||
Reference in New Issue
Block a user