mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-23 04:09:49 +00:00
Fix usage logging dedupe and reduce stats churn
- batch console log buffer events and support batched SSE log messages - debounce usage stats update/pending events to reduce UI/runtime churn - avoid awaiting request-success bookkeeping before returning provider responses - deduplicate identical usage writes in usageHistory/daily aggregates - reduce default logger verbosity from DEBUG to INFO (overridable via LOG_LEVEL) Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
ec096d2add
commit
0d21668917
@@ -47,6 +47,11 @@ export default function ConsoleLogClient() {
|
||||
const next = [...prev, msg.line];
|
||||
return next.length > CONSOLE_LOG_CONFIG.maxLines ? next.slice(-CONSOLE_LOG_CONFIG.maxLines) : next;
|
||||
});
|
||||
} else if (msg.type === "lines") {
|
||||
setLogs((prev) => {
|
||||
const next = [...prev, ...msg.lines];
|
||||
return next.length > CONSOLE_LOG_CONFIG.maxLines ? next.slice(-CONSOLE_LOG_CONFIG.maxLines) : next;
|
||||
});
|
||||
} else if (msg.type === "clear") {
|
||||
setLogs([]);
|
||||
}
|
||||
|
||||
@@ -7,13 +7,14 @@ initConsoleLogCapture();
|
||||
export async function GET(request) {
|
||||
const encoder = new TextEncoder();
|
||||
const emitter = getConsoleEmitter();
|
||||
const state = { closed: false, send: null, sendClear: null, keepalive: null };
|
||||
const state = { closed: false, send: null, sendLines: null, sendClear: null, keepalive: null };
|
||||
|
||||
// Idempotent: safe to call from request.signal abort, cancel(), or enqueue failure.
|
||||
const cleanup = () => {
|
||||
if (state.closed) return;
|
||||
state.closed = true;
|
||||
if (state.send) emitter.off("line", state.send);
|
||||
if (state.sendLines) emitter.off("lines", state.sendLines);
|
||||
if (state.sendClear) emitter.off("clear", state.sendClear);
|
||||
if (state.keepalive) clearInterval(state.keepalive);
|
||||
};
|
||||
@@ -40,6 +41,15 @@ export async function GET(request) {
|
||||
}
|
||||
};
|
||||
|
||||
state.sendLines = (lines) => {
|
||||
if (state.closed || !Array.isArray(lines) || lines.length === 0) return;
|
||||
try {
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: "lines", lines })}\n\n`));
|
||||
} catch {
|
||||
cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
// Notify client when cleared
|
||||
state.sendClear = () => {
|
||||
if (state.closed) return;
|
||||
@@ -51,6 +61,7 @@ export async function GET(request) {
|
||||
};
|
||||
|
||||
emitter.on("line", state.send);
|
||||
emitter.on("lines", state.sendLines);
|
||||
emitter.on("clear", state.sendClear);
|
||||
|
||||
// Keepalive ping every 25s
|
||||
|
||||
Reference in New Issue
Block a user