Skip to content

Add local-node log viewer to the dashboard - #2237

Open
alytaphoenix wants to merge 1 commit into
exo-explore:mainfrom
alytaphoenix:feature/log-viewer
Open

Add local-node log viewer to the dashboard#2237
alytaphoenix wants to merge 1 commit into
exo-explore:mainfrom
alytaphoenix:feature/log-viewer

Conversation

@alytaphoenix

Copy link
Copy Markdown

Summary

  • Adds a "Logs" page to the dashboard for viewing this node's application logs (main process log + runner stdout/stderr) without needing terminal/SSH access.
  • New backend endpoints: GET /v1/logs (list), GET /v1/logs/{name} (tail, JSON), GET /v1/logs/{name}/raw (full file download), modeled on the existing traces endpoints.
  • name is restricted to a fixed whitelist (main / runner_stdout / runner_stderr) mapped to known paths — never joined with client input, so there's no path traversal surface.
  • Tail reads at most 2MB from the end of the file (_tail_file), so large/unbounded logs don't get loaded in full.
  • Local-node only by design (no cross-node aggregation) — exo is distributed and each node writes its own log; aggregating logs across a cluster would be a separate, much larger feature.

Test plan

  • uv run basedpyright — 0 new errors (baseline unchanged at 319 pre-existing errors from unrelated mlx import resolution issues in this sandbox)
  • uv run ruff check / ruff format — clean
  • uv run pytest src/exo/api/tests/test_logs_api.py — 10/10 passing, including a regression test for a lines<=0 tail-length edge case caught during review
  • uv run pytest src/exo (excluding suites that require the mlx package, unavailable in this sandbox and failing identically on main) — 331 passed, 3 skipped
  • npx svelte-check — no new errors (baseline 15 errors / 6 warnings unchanged)
  • Manually verified in a real browser (Playwright): nav link, log selector, tail content rendering, and file download all work end-to-end against a running exo instance
  • nix fmt / nix flake check were not run (nix isn't available in this sandbox) — substituted ruff format + prettier-plugin-svelte directly, which should match, but this hasn't been confirmed against the real treefmt config

🤖 Generated with Claude Code

https://claude.ai/code/session_011rjSfwDBTkmySmfU6NgHKF

Adds GET /v1/logs, /v1/logs/{name}, /v1/logs/{name}/raw for the main
process log and the runner stdout/stderr logs, modeled on the existing
traces endpoints. name is restricted to a fixed whitelist so there is
no path traversal surface. Adds a Logs page (list + tail view +
download) reachable from the header nav.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011rjSfwDBTkmySmfU6NgHKF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant