From c7a0bd2523c024c6bed5d68c01024b03ff516052 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 13 Feb 2026 09:11:25 +0000 Subject: [PATCH] feat(dashboard): per-actor logging with tracing integration (Stage 7) Add actor-level tracing span in worker tick_all to propagate actor_addr to user log events. DashboardLayer now extracts actor_addr from both span extensions and event fields. EventStore gains read_for_actor() for filtered log queries. Web actor detail page gets a live-updating log panel with per-level filter buttons (ERR/WARN/INFO/DBG/TRC) and auto-scroll. TUI actor detail view adds scrollable log panel with j/k navigation and 1-5 keys for level toggling. REST endpoint at /api/logs?actor=&limit=N&level=L. Authored by Claude, lovingly guided by Zachery Aaron Shores-Chmielewski --- .../src/actor_detail_html.rs | 124 ++++++++++++++++++ crates/runtime-dashboard/src/layer.rs | 61 +++++++-- crates/runtime-dashboard/src/server.rs | 29 ++++ crates/runtime-dashboard/src/tui/app.rs | 82 ++++++++++++ crates/runtime-dashboard/src/tui/mod.rs | 7 + crates/runtime-dashboard/src/tui/ui.rs | 79 ++++++++++- src/worker.rs | 3 + 7 files changed, 372 insertions(+), 13 deletions(-) diff --git a/crates/runtime-dashboard/src/actor_detail_html.rs b/crates/runtime-dashboard/src/actor_detail_html.rs index 1c7398b..9f6fdb5 100644 --- a/crates/runtime-dashboard/src/actor_detail_html.rs +++ b/crates/runtime-dashboard/src/actor_detail_html.rs @@ -62,6 +62,40 @@ pub const ACTOR_DETAIL_HTML: &str = r##" .sparkline-panel h3 { font-size: 11px; color: #888; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 8px; } .sparkline-panel svg { width: 100%; height: 50px; } + .logs-panel { + background: #161822; border: 1px solid #2a2d3e; border-radius: 6px; + padding: 14px; margin-bottom: 12px; + } + .logs-panel h3 { + font-size: 11px; color: #888; text-transform: uppercase; letter-spacing: 1px; + margin-bottom: 8px; display: flex; align-items: center; gap: 12px; + } + .level-filter { display: flex; gap: 4px; } + .level-btn { + background: #1e2030; border: 1px solid #2a2d3e; border-radius: 3px; + color: #888; font-size: 10px; padding: 1px 6px; cursor: pointer; + font-family: inherit; + } + .level-btn.active { border-color: #555; color: #fff; } + .level-btn.error { color: #f44336; } + .level-btn.warn { color: #ff9800; } + .level-btn.info { color: #2196f3; } + .level-btn.debug { color: #888; } + .level-btn.trace { color: #555; } + + .log-list { + max-height: 400px; overflow-y: auto; font-size: 11px; line-height: 1.6; + } + .log-entry { display: flex; gap: 8px; padding: 1px 0; border-bottom: 1px solid #1a1c2e; } + .log-time { color: #555; white-space: nowrap; min-width: 80px; } + .log-level { font-weight: 700; min-width: 50px; } + .log-level.ERROR { color: #f44336; } + .log-level.WARN { color: #ff9800; } + .log-level.INFO { color: #2196f3; } + .log-level.DEBUG { color: #888; } + .log-level.TRACE { color: #555; } + .log-msg { color: #e0e0e0; word-break: break-all; } + ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: #0f1117; } ::-webkit-scrollbar-thumb { background: #2a2d3e; border-radius: 3px; } @@ -113,6 +147,21 @@ pub const ACTOR_DETAIL_HTML: &str = r##"

Mailbox Depth

+ +
+

+ Logs + (0) +
+ + + + + +
+

+
+