Skip to main content
Logs arrive over the same OTLP endpoint as everything else. What separates a useful log setup from a noisy one is not the transport — it is which fields you populate on the way in, because those are what search, filtering and trace correlation are built on.
Before you start, you need two values.
  1. Your base endpoint — shown on Get Started in the dashboard. These pages write it as $OIQ_ENDPOINT.
  2. A license key — created in Settings → API keys, starting oiq_. Requires the Admin role. See Create a license key. These pages write it as $OIQ_LICENSE_KEY.
Export both before running anything below:

The fields that matter

Every log line is stored with these, and each one drives something you can do with it later:
Trace correlation is free, but only if the log is emitted inside the span. trace_id and span_id are populated by the SDK’s log appender from the active context. A line written from a background goroutine or a detached worker has no active span and lands with empty ids — which is correct, not a bug, but it will not link.

Sending logs

Use your language’s OpenTelemetry log appender so the SDK attaches trace context automatically. The endpoint and headers are the same two variables used for traces and metrics:
Use OTLP over HTTP with an oiq_ key. The gRPC path expects a signed license JWT and will reject a dashboard-issued key with an authentication error that looks like a network problem.

Parse before you send, not after

A log line stored as one opaque string is searchable but not filterable. Parsing JSON at the Collector — or emitting structured logs from the application — turns fields into attributes you can filter on directly, which is both faster and cheaper than a full-text scan. The rule of thumb: anything you will ever want to filter by should be an attribute; anything you will only ever read can stay in the body.

What you get once logs arrive

Search

Full-text over the body, plus field filters and a query syntax for combining them.

Live tail

A streaming view of lines as they arrive, filtered the same way.

Patterns

Clusters near-identical lines so a million repeats read as one pattern with a count.

Retention

Logs are kept for the retention window on your plan — 30 days unless your plan says otherwise. Retention is applied on read as well as on storage, so a search over a wider range than your plan allows returns what is inside the window rather than erroring.

Volume control

Logs are usually the highest-volume signal. Two levers, in order of effect:
  1. Do not ship debug level from production. Filter at the source, where it costs nothing.
  2. Drop known-noisy lines at the Collector with a filter processor — health check hits, readiness probes, chatty third-party libraries.
Sampling logs is a poor third option: unlike traces, a sampled log set answers “how many times did this happen” wrongly.

Troubleshooting

The resource has no service.name. Add it with a resource processor in the Collector, or set OTEL_SERVICE_NAME in the application.
The parser did not find the timestamp field, so the receive time was used instead. Check the timestamp.parse_from path and the layout string against an actual line.

Next

Set up Monitoring

Metrics and traces, so log lines have traces to link to.

Set up Infrastructure

Hosts, containers and Kubernetes.