Stream device logs (follow mode)
const url = 'http://localhost:3000/api/v1/devices/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/logs/stream?severity=DEBUG&source=my-container&q=connection%20refused';const options = { method: 'GET', headers: {'last-event-id': 'example', 'X-API-Key': '<X-API-Key>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'http://localhost:3000/api/v1/devices/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/logs/stream?severity=DEBUG&source=my-container&q=connection%20refused' \ --header 'X-API-Key: <X-API-Key>' \ --header 'last-event-id: example'Server-Sent Events stream of new log lines for a device as they arrive, honoring the same severity/source/q filters as the paged /logs endpoint (FM-773, composed through the same buildDeviceLogQuery() builder). Implemented as short-interval polling of Loki’s query_range, re-emitted as SSE — see LogStreamService for why. Named events on the stream: log (a LogEntryDto, id set to a resumable <timestampMs>:<seq> cursor — reconnect with the Last-Event-ID header to resume exactly after it, which browsers do automatically on a dropped connection), heartbeat (keepalive, ~15s, survives idle proxies), skip ({ skipped: number }, emitted when the server had to drop the oldest lines of a poll tick under backpressure rather than buffer unboundedly), error (a transient upstream query failure; the stream keeps polling), and permission-revoked (the stream ends immediately after — the caller’s TELEMETRY_READ permission is re-checked periodically, not only at connect). Subject to per-organization and per-user concurrent-connection caps — 429 Too Many Requests when exceeded, returned as an ordinary JSON response before any SSE headers are sent.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Device UUID
Query Parameters
Section titled “Query Parameters”Filter by severity level
Example
my-containerFilter by log source (container name, service, or “system”)
Example
connection refusedFull-text search against the log message body, same semantics as the paged endpoint.
Header Parameters
Section titled “Header Parameters”UUID of the organization (tenant) the request acts in. It selects the tenant and grants nothing: the server checks membership or an open tenant switch. Not needed for global operations. A malformed value returns 400. API keys are fixed to their own organization; another organization returns 403. The x-organization-source header grants nothing.
Responses
Section titled “Responses”Text/event-stream of device log events
Forbidden — caller lacks required permission
Device not found
Too many concurrent log stream connections for this organization or user