MCPcopy Index your code
hub / github.com/BlockRunAI/ClawRouter / formatRecentLogs

Function formatRecentLogs

src/stats.ts:302–356  ·  view source on GitHub ↗
(days: number = 1)

Source from the content-addressed store, hash-verified

300 * Reads the last N days of log files and shows each request individually.
301 */
302export async function formatRecentLogs(days: number = 1): Promise<string> {
303 const logFiles = await getLogFiles();
304 const filesToRead = logFiles.slice(0, days);
305
306 const allEntries: UsageEntry[] = [];
307 for (const file of filesToRead) {
308 const entries = await parseLogFile(join(LOG_DIR, file));
309 allEntries.push(...entries);
310 }
311
312 // Sort chronologically (oldest first)
313 allEntries.sort((a, b) => a.timestamp.localeCompare(b.timestamp));
314
315 const lines: string[] = [];
316 lines.push("╔════════════════════════════════════════════════════════════════════════╗");
317 lines.push(
318 `║ ClawRouter Request Log — last ${days === 1 ? "24h" : `${days} days`}`.padEnd(72) + "║",
319 );
320 lines.push("╠══════════════════╦══════════════════════════╦═════════╦══════╦════════╣");
321 lines.push("║ Time ║ Model ║ Cost ║ ms ║ Status ║");
322 lines.push("╠══════════════════╬══════════════════════════╬═════════╬══════╬════════╣");
323
324 if (allEntries.length === 0) {
325 lines.push("║ No requests found".padEnd(72) + "║");
326 }
327
328 let totalCost = 0;
329 for (const e of allEntries) {
330 const time = e.timestamp.slice(11, 19); // HH:MM:SS
331 const date = e.timestamp.slice(5, 10); // MM-DD
332 const displayTime = `${date} ${time}`;
333 const model = e.model.length > 24 ? e.model.slice(0, 21) + "..." : e.model;
334 const cost = `$${e.cost.toFixed(4)}`;
335 const ms = e.latencyMs > 9999 ? `${(e.latencyMs / 1000).toFixed(1)}s` : `${e.latencyMs}ms`;
336 const status =
337 (e as UsageEntry & { status?: string }).status === "error" ? " ERROR " : " OK ";
338 totalCost += e.cost;
339 lines.push(
340 `║ ${displayTime.padEnd(16)}║ ${model.padEnd(24)}║ ${cost.padStart(7)}║ ${ms.padStart(4)}║${status}║`,
341 );
342 }
343
344 lines.push("╠══════════════════╩══════════════════════════╩═════════╩══════╩════════╣");
345 lines.push(
346 `║ ${allEntries.length} request${allEntries.length !== 1 ? "s" : ""} Total spent: $${totalCost.toFixed(4)}`.padEnd(
347 72,
348 ) + "║",
349 );
350 lines.push(
351 "║ Logs: ~/.openclaw/blockrun/logs/ (JSONL — one entry per request)".padEnd(72) + "║",
352 );
353 lines.push("╚════════════════════════════════════════════════════════════════════════╝");
354
355 return lines.join("\n");
356}
357
358/**
359 * Delete all usage log files, resetting stats to zero.

Callers 1

mainFunction · 0.85

Calls 2

getLogFilesFunction · 0.85
parseLogFileFunction · 0.85

Tested by

no test coverage detected