build-logs: SSE live streaming + raw download (#726 phase 4)
Backend (hive-c0re):
- build_logs.rs: add tokio::sync::broadcast::Sender<i64> to BuildLogs;
append() and finish() notify subscribers after each sqlite write.
Add BuildLogProgress struct and get_progress(id, stdout_cursor,
stderr_cursor) for incremental delta reads.
- dashboard.rs: two new endpoints —
GET /api/build-logs/id/{id}/stream SSE; streams BuildLogFrame
{stdout_append, stderr_append, status?, done} deltas until the
build finishes or the browser disconnects. Backed by an mpsc
channel task that watches the per-build broadcast notifications.
GET /api/build-logs/id/{id}/raw text/plain download with
Content-Disposition: attachment; filename build-log-{agent}-{id}.txt
Frontend (dashboard):
- tabs.js: running builds (status === null) connect an EventSource to
/stream and append lines live; "live" badge pulses amber while active,
flips to ok/fail on done. Finished builds still use the JSON fetch path.
Collapsing a running panel closes the EventSource; re-expanding
reconnects. Adds a "⬇ raw" download link to every expanded row.
- dashboard.css: .build-logs-dl inline download link; .build-logs-live
live pulse @keyframes animation.
Docs: web-ui.md updated for all three new endpoints + behaviour.
This commit is contained in:
parent
c4ce91b61f
commit
050e130eba
5 changed files with 365 additions and 14 deletions
|
|
@ -642,12 +642,17 @@ fetch entirely.
|
|||
- `↳ build logs · <agent>` — opens the side panel and fetches
|
||||
the last 10 build-log headers via
|
||||
`GET /api/build-logs/{agent}` (status chip + kind + age +
|
||||
truncated cmdline per row). Clicking a row lazy-fetches its
|
||||
full stdout+stderr from `GET /api/build-logs/id/{id}` and
|
||||
expands it inline as a scrollable `<pre>`. A refresh button
|
||||
re-fetches the header list. Backed by the `build_logs.sqlite`
|
||||
store that `lifecycle::run` and `lifecycle::prebuild_toplevel`
|
||||
write into.
|
||||
truncated cmdline per row). Clicking a row expands the detail
|
||||
inline: finished builds lazy-fetch `GET /api/build-logs/id/{id}`
|
||||
(full JSON); running builds (`status: null`) instead open an
|
||||
`EventSource` to `GET /api/build-logs/id/{id}/stream` and
|
||||
stream stdout/stderr live — the "live" badge pulses amber while
|
||||
the build runs and flips to the final status colour on
|
||||
completion. A `⬇ raw` link downloads the full log as
|
||||
`text/plain` via `GET /api/build-logs/id/{id}/raw`. A refresh
|
||||
button re-fetches the header list. Backed by the
|
||||
`build_logs.sqlite` store that `lifecycle::run` and
|
||||
`lifecycle::prebuild_toplevel` write into.
|
||||
- Plain navigation links (config repo, forge profile,
|
||||
`dashboardLinks` extras) now live in the icon-only nav strip
|
||||
on Line 1 — see above. The agent's `config` link
|
||||
|
|
@ -855,6 +860,21 @@ that's a browser-level decision, not ours.
|
|||
`BuildLogFull` (JSON): all header fields plus `stdout` and
|
||||
`stderr` as plain text (newline-terminated lines, utf-8). HTTP
|
||||
404 when the row is missing (vacuum-reaped or stale id).
|
||||
- `GET /api/build-logs/id/{id}/stream` — SSE stream for live
|
||||
monitoring of a running build. The client connects while the
|
||||
build's `status` is `null`; the server sends incremental
|
||||
`BuildLogFrame` JSON frames: `{ stdout_append, stderr_append,
|
||||
status?, done }`. The first frame carries the full accumulated
|
||||
log since build start (cursors at 0); subsequent frames carry
|
||||
only new bytes. `done: true` on the final frame signals the
|
||||
browser to close the `EventSource`. The stream closes on its
|
||||
own once the build finishes, or if the row is vacuum-reaped
|
||||
mid-stream. An `error` event name signals a server-side failure
|
||||
(row not found, etc.).
|
||||
- `GET /api/build-logs/id/{id}/raw` — plain-text download of the
|
||||
full log (stdout followed by `\n--- stderr ---\n` + stderr when
|
||||
non-empty). `Content-Disposition: attachment` triggers a
|
||||
browser download; filename is `build-log-{agent}-{id}.txt`.
|
||||
- `GET /api/journal/{name}?unit=&lines=` — journalctl viewer for
|
||||
a managed container; rendered in the side panel.
|
||||
- `GET /api/approval-diff/{id}?base=applied|approved|previous` —
|
||||
|
|
|
|||
Loading…
Reference in a new issue