Belune

Server-Sent Events (SSE)

One-way streams you can tail with curl — logs, metrics, request traces and notifications.

Belune has seven endpoints that stream with Server-Sent Events rather than returning a body and closing. Each is a plain GET that stays open, so curl is a complete client — no library, no handshake.

curl -N -H "Authorization: Bearer $BELUNE_TOKEN" \
  "https://belune.example.com/api/projects/$PROJECT_ID/applications/$APP_ID/logs?follow=true"

-N disables curl's output buffering, so lines print as they arrive rather than in blocks.

The Streams

EndpointScopeCarries
/projects/{p}/applications/{a}/logsreadContainer output — history, then optionally live
/projects/{p}/applications/{a}/deployments/{d}/build-logsreadBuild output for one deployment
/projects/{p}/applications/{a}/requests/streamreadProxy request traces for one application
/requests/streamread, AdminRequest traces across every application
/projects/{p}/applications/{a}/metrics/streammetricsOne application's container stats
/metrics/host/streammetrics, AdminHost CPU, memory and disk
/notifications/streamreadYour notifications as they arrive

Frame Format

Every response is Content-Type: text/event-stream. Three kinds of frame appear:

data: {"level":"info","message":"listening on :3000"}

event: done
data: log stream ended

: ping
  • data: alone — the payload, and the common case. Its shape depends on the stream: a raw log line for logs, a JSON object for metrics, request traces and notifications.
  • event: with a name — a control frame. Only error and done are used, and only by the two log streams.
  • : comment — a keep-alive, sent as : ping every 30 seconds on the long-lived streams. Ignore it; it exists to hold the connection open through proxies and to force headers to flush.

The two log streams close on their own: event: done means the source ended (the build finished, or the container's log ended). The other five run until you disconnect.

Reading History

/applications/{id}/logs is the one stream that is not live-only:

RequestBehaviour
GET .../logsThe container's whole log buffer, then closes
GET .../logs?follow=trueThe whole buffer, then stays open and tails

It reads the container's own logs, so "history" means whatever Docker still holds for that container — not what Belune has stored. For a bounded, queryable page of retained history instead, use .../logs/history, which reads the collector's database and takes filters.

Choosing Between the Two

Both transports carry live data, but they answer different questions.

Server-Sent Events is one stream per thing, over ordinary HTTP. Reach for it when you are scripting: one curl, an Authorization header, and a pipe. It is also the only way to read a container's log history over the API.

The WebSocket hub is one connection carrying many channels, subscribed to and unsubscribed from at will. Reach for it when you want several feeds at once — a dashboard watching metrics, logs and status together — and can afford a WebSocket client.

The hub is live-only. Nothing is buffered from before you subscribe, on any channel, so it cannot replace ?follow=false on the log stream.

One practical difference for browsers: EventSource cannot send an Authorization header, so in-browser callers authenticate these streams with the dashboard session cookie. A script sending a bearer token has no such limit.

Limits

The rate limit applies at connection time, not per frame — an open stream costs one request no matter how much it carries. Each connection holds a server-side reader for as long as it is open, so close streams you are no longer reading.

On this page