Logs
Logs are timestamped events. In avuru obs they become powerful when they carry a
trace_id — that's what lets you pivot from a slow trace straight to the lines
the service logged during that request.
- Ingestion — via OTLP logs or the collector's log receivers.
- Correlation — by
trace_id/span_idand resource attributes.
What your service should emit
With the logs module and node-agent stdout collection enabled, pod logs flow through the gateway. Check the selected project and collection configuration. To get useful logs, emit one JSON object per line carrying these three things:
| Field | Why |
|---|---|
level | Becomes SeverityNumber. Both dialects are understood: numeric (pino: 30, 50) and named (logback: "INFO", "ERROR"). |
trace_id | Becomes the TraceId column — this, and only this, is what makes a trace show its logs. |
span_id | Becomes SpanId, narrowing a log to the operation inside the trace. |
Anything else in the object becomes a queryable log attribute, and the raw line stays searchable in full text.
Lines that are not JSON are ingested unchanged rather than rejected, and the
node agent still reads a level off them where one is written: a level=warn /
lvl= / severity= pair (logfmt, zap console), or the usual upper-case token
bounded on both sides — … DEBUG [main] …, [INFO], ERROR: — as Spring,
logback and log4j write it. Without any of those, a record's severity stays
unset — and severity is a floor comparison, so such a record matches no
severity filter at all and is never promoted to an
error issue (which keys on ERROR and above). A record
that already carries a level, such as one exported over OTLP by an SDK, is left
alone. The parsing is on by default and off with
sensor.agent.logs.parseSeverity=false.
Getting trace_id onto the line is the language runtime's job:
- Node / pino — a
mixinreadingtrace.getActiveSpan()?.spanContext(). Do not rely on@opentelemetry/instrumentation-pinoin an ESM service: it patches nothing without the loader hook, and the omission is silent. - Java / logback — the Micrometer tracing MDC keys, already present in the standard console pattern.
:::note Prefer stdout to OTLP logs
A service that also exports logs over OTLP is ingested twice, since the
node agent is already reading its stdout. An SDK-emitted record also carries no
k8s.namespace.name, so the gateway cannot tell which project it belongs to
and files it under the fallback tenant. Set the signal-specific
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT rather than the generic
OTEL_EXPORTER_OTLP_ENDPOINT, which switches on every signal at once.
:::
Explore logs
The logs explorer is live today:
- Full-text search over the log body, with severity, tags, sources and a multi-service selector. Suggestions include services known only from logs; Kubernetes workloads include their namespace so namesakes stay distinct. An exact service name can also be entered directly. Every filter is held in the URL for shareable views.
- One stream or separate panels. The merged view orders all selected services and workloads on one timeline. The panel view gives every selection its own scroll and pagination while keeping the same time, severity, source and text filters. It runs at most four storage requests concurrently.
- Application and mesh sources together. Application, ztunnel, waypoint and uncategorised records are enabled by default and can be switched independently. Every row names both its emitting service and source. The same explorer is available from Signals → Logs and the mesh's Logs tab.
- Trace correlation — a log row's
trace_idlinks to its trace, and a trace's spans link back to the logs emitted during that request. - Keyset pagination for gap-free scrolling through large time windows.
- A service's logs, including the mesh's. A service's Logs tab finds its lines even when its pod files them under a different name than its spans carry: the hub ties the service to its workload and reads the same sources as a workload's Logs tab on the mesh screen. When no workload can be tied to it, the tab says which of two things to fix.
- Take the lines with you. Copy every loaded line, or tick the rows that
matter (shift-click extends a range) and copy just those, or download what is
loaded as a
.logfile. Each control says how many lines it will take. The per-row copy button appears on hover and on keyboard focus.
Query the API
GET /api/v1/logs accepts repeated service parameters and repeated
workload=namespace/name parameters. Repeat source, or pass
source=app,ztunnel,waypoint,other, to select source families; the subjects
are combined with OR, then q, severity and tags are applied with AND.
GET /api/v1/logs/services returns
the project-scoped service and workload suggestions for the requested time
window. See the API reference for cursor and resolution
details.
Verify trace correlation
A structured stdout record can carry these fields:
{"level":"INFO","message":"payment authorized","trace_id":"0123456789abcdef0123456789abcdef","span_id":"0123456789abcdef"}
These IDs are illustrative. In an application, copy them from the active span; never use a fixed ID for real requests. A trace ID has 32 hexadecimal characters and a span ID has 16. Invalid or absent IDs do not identify a request.
Find the record in Logs, open its trace link and verify that the span belongs to the same request. For an executable example, use the Go SDK integration or the synthetic checkout exercise.
If the logs are not attached to a trace
- A plain line can remain searchable without having trace context.
- Service name and timestamp alone are not a trace ID.
- Check project, time window, retention and the signal's collection module.
- Choose one ingestion path for a log to avoid collecting the same event twice.
Retention is configured by deployment and project; see scaling and retention.
:::note Release coverage Automatic severity parsing from container stdout and the expanded service-log and copy controls described above are documented on the current development trunk for v0.17. The multi-service explorer and mesh-wide Logs tab are also documented from the current development trunk. OTLP log ingestion and trace-ID correlation are already released. Check feature status and the version you installed. :::