feat(logs): stream logs with follow#20
Conversation
The deployment follow loop returned as soon as the log stream closed, skipping the duplicate-suppressed catch-up search whenever the stream ended (EOF) before the poller observed a terminal status. Keep polling after a clean stream shutdown and check terminal status immediately so the catch-up search still runs without waiting for the next poll.
The runtime --follow loop ended as soon as the SSE stream closed, so a dropped connection (load-balancer cap, redeploy, network blip) silently stopped the tail even though the backend supports resuming. Reconnect from the last stream cursor (Last-Event-ID) until the context is canceled, relying on the server's overlap window and seen-set dedup to avoid replaying recent events. Deployment (build) follow is unchanged: its terminal poll and duplicate-suppressed catch-up search already recover logs missed during a disconnect.
marckong
left a comment
There was a problem hiding this comment.
Summary
Adds a --follow flag to function/frontend log commands, backed by a new no-timeout SSE stream client (internal/api/log_stream.go) and a shared follow-loop package (internal/logfollow). Runtime follows reconnect transparently from the last event cursor; build follows stop at terminal deployment status and run a duplicate-suppressed catch-up search. The bulk of the +2478/-2476 line count is a regeneration of apiclient/client.gen.go.
- New stream client manually sets
Authorization: Bearer/Accept: text/event-streamand a 1 MB SSE scanner buffer, separate from the timeout-bound default client. logfollow.Deploymentcoordinates a reader goroutine + terminal-status poller;logfollow.Runtimewraps a self-reconnecting stream.
Review
Clean, well-structured change with solid test coverage — build, go test, and the affected packages all pass locally. The concurrency in the deployment follow loop is careful (buffered errCh, awaitStream before snapshot, defer cancel()), so the catch-up reads printed only after the reader goroutine has exited — no races or goroutine leaks spotted. A few verifications worth noting:
- Dropping
resp.JSON503insearchProjectLogsis correct — the regeneratedSearchProjectLogsClientResponseno longer has that field, so it's required to compile. - The manual
Bearerscheme in the stream client matchesauthorizationEditor, andprojectLogsStreamURLcorrectly handles the trailing slash fromgeneratedClientBaseURL. - Terminal-status sets (
active/deleted/deleting/failed, excludingprovisioning) line up with the generated enums.
Overall correctness: correct. No blocking issues; existing code and tests are unaffected. Approving. 🚀
Summary
Depends on Kong/volcano-hosting#471.
Tests