P3 follow-up: log download (txt + ndjson) on the live job page
The diff job's full output streams to the standard live job log page,
which can be a lot of text the operator wants to grep through or paste
into a ticket. Add a Download button.
Source of truth is the persisted job_logs table — works any time
(running or finished) and doesn't need to pause the live WS stream.
The download is 'everything the server has up to right now'; if the
operator wants a fuller snapshot of a still-running job, they hit
Download again.
- New endpoint GET /api/jobs/{id}/log.{txt,ndjson} (chi {format}
matcher constrained to the two known suffixes). Auth via session
cookie. 404 on unknown job.
- internal/server/http/job_download.go writeLogsText emits a small
header + 'HH:MM:SS.mmm TAG payload' rows mirroring what the live
page shows. writeLogsNDJSON emits one self-contained {seq,ts,stream,
payload} JSON object per line — appending stays valid (each line
stands alone), and the whole file pipes cleanly into jq. NDJSON is
newline-delimited JSON; not the same as a JSON array.
- web/templates/pages/job_detail.html grows two header buttons:
'Download log' (txt) + '.ndjson' ghost variant for tooling.
Tests cover the txt format (header + per-row shape), the ndjson
format (each line round-trips through json.Unmarshal), unknown job
404, unauthenticated 401.
This commit is contained in:
@@ -63,6 +63,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<a href="/api/jobs/{{$job.ID}}/log.txt" class="btn"
|
||||
title="Download the full log up to this moment (works while running too).">
|
||||
Download log
|
||||
</a>
|
||||
<a href="/api/jobs/{{$job.ID}}/log.ndjson" class="btn btn-ghost" title="Same log as NDJSON for jq / tooling">.ndjson</a>
|
||||
{{if $page.IsActive}}
|
||||
<button class="btn btn-danger" id="cancel-btn"
|
||||
hx-post="/api/jobs/{{$job.ID}}/cancel"
|
||||
|
||||
Reference in New Issue
Block a user