1.7 KiB
Overview
Realtime browser log display is a one-way stream, so the platform exposes Server-Sent Events instead of WebSocket for this change. SSE gives the browser one long-lived HTTP response, works with standard EventSource, carries same-origin HttpOnly session cookies, and only needs Nginx buffering disabled.
Transport Boundary
Run continues to upload logs through POST /api/v1/run/logs/batches. That path remains durable and retryable: Run writes to local spool, sends bounded batches, receives sequence ACKs, and can retry without depending on browser presence.
Run log capture remains plugin-declared. For live terminal output, Run captures the supervised process channels declared by the plugin as process.stdout / process.stderr; game file tails such as file.tail are explicit plugin-declared history/backfill sources rather than a generic default. A managed process started by Run writes stdout/stderr into Run-owned capture files and Run tails those capture files into durable batch ingest, so restarting Run can resume transmission for an already-running supervised process without inspecting game-specific logs such as SCUM.log.
The browser subscribes to GET /api/v1/server-instances/{id}/logs/events. Platform authorizes the user session against the server instance, replays a bounded recent history per stream, then publishes newly ingested log entries from memory fan-out. POST /api/v1/log-streams/query stays as an explicit historical cursor API, not a realtime polling loop.
Proxy Notes
SSE does not require Upgrade or Connection: upgrade. Reverse proxies must avoid buffering the stream and should keep the upstream read timeout long enough for idle log periods.