Before you start, you need two values.
- Your base endpoint — shown on Get Started in the dashboard. These
pages write it as
$OIQ_ENDPOINT. - A license key — created in Settings → License Keys, starting
oiq_. Requires the Admin role. See Create a license key. These pages write it as$OIQ_LICENSE_KEY.
sudo on a host with systemd, and outbound HTTPS to your ingest
endpoint.
Why a package rather than a container
On a host whose job is running your application, a containerised collector adds a layer that gets in the way of the thing you most want: host metrics. A container sees its own filesystem and its own process namespace, so collecting real host telemetry from inside one means mounting the host back in and telling the receiver where you put it. Installed natively, it just sees the host. It also restarts with the machine without a container runtime having to be up first.1. Install the collector
otelcol-contrib, and a
default config at /etc/otelcol-contrib/config.yaml. It starts the service
immediately on the default config, which exports nowhere — the next two steps
replace it.
2. Supply the endpoint and key
The key must not live in the config file, which is world-readable. systemd reads an environment file you can lock down instead:3. Write the config
The OTLP receivers bind to
127.0.0.1, not 0.0.0.0. On a VM, the things
exporting to this collector are on the same machine, so loopback is sufficient
and it means the collector is not an open OTLP relay reachable from your
network. Change it only if you deliberately want other hosts to export here,
and put a firewall in front of it if you do.journald collects system logs. Narrow units to what you actually want —
without a filter, a busy host will ship a great deal of noise you pay to store.
Remove the journald receiver from the logs pipeline if you do not want
system logs at all.
4. Start it
systemctl status otelcol-contrib:
active (running) — and, critically, still running thirty seconds later. A
collector that fails on its config exits and systemd restarts it in a loop, which
reads as “running” if you look at exactly the wrong moment.
Confirm from the log:
5. Point applications at it
Applications on this host export to loopback and carry no license key:EnvironmentFile rather
than in a shell profile — a profile is not read by a unit.
Verify
The collector publishes its own metrics on port8888. Three counters separate
the two things that can be wrong:
Accepted rising while sent stays flat is the classic signature of a wrong
endpoint or a missing key in the exporter block. It is worth checking before
anything else, because from inside your application everything looks fine.
Expected output within a minute of start, with host metrics flowing:
resourcedetection sets it from
the OS.
Troubleshooting
The service restarts in a loop
The service restarts in a loop
A config error. The collector refuses to run on an invalid configuration
rather than running degraded, and systemd restarts it.Validate before restarting:No output and exit code
0 means the config is valid.'environment variable OIQ_ENDPOINT not found'
'environment variable OIQ_ENDPOINT not found'
The unit is not reading your environment file.
systemctl edit writes a
drop-in at /etc/systemd/system/otelcol-contrib.service.d/override.conf —
confirm it exists and contains the EnvironmentFile line, then
sudo systemctl daemon-reload.Exporting the variables in your shell does not reach a systemd unit.No journald logs arrive
No journald logs arrive
The collector user must be able to read the journal. The package normally
handles this; where it has not, add the service user to the Also check your
systemd-journal
group and restart:units filter actually matches units on this host —
systemctl list-units --type=service shows the real names.Host metrics are missing while traces arrive
Host metrics are missing while traces arrive
The
hostmetrics receiver is in the metrics pipeline only. Confirm it is
listed under service.pipelines.metrics.receivers; a receiver defined but
not wired into a pipeline is silently inert — no error, no data.The collector starts, then logs 'Exporting failed. Will retry'
The collector starts, then logs 'Exporting failed. Will retry'
Read the
error field on that line — it names the cause exactly.no such host— the endpoint hostname does not resolve. Check$OIQ_ENDPOINTagainst the value on Get Started.connection refused— the host resolves but nothing is listening on that port.401 Unauthorized— the key is missing, malformed or revoked.404— the endpoint already ends in/v1/…. It must be the base URL; the collector appends the signal path itself.
Nothing at all in the logs after 'Everything is ready'
Nothing at all in the logs after 'Everything is ready'
The collector is running and receiving nothing. That is an application-side
problem, not a collector one — your services are not exporting to it.Check that your application’s
OTEL_EXPORTER_OTLP_ENDPOINT points at the
collector’s OTLP port (4318 for HTTP, 4317 for gRPC), not at aiAxonIQ.401 with a key you know is correct
401 with a key you know is correct
Two causes that are not about the key’s value:
- A trailing newline. A key read from a file created by a shell heredoc,
or a Kubernetes Secret made with
--from-file, carries the newline as part of the value. Use--from-literal, orprintfrather thanecho. - A validation outage. If the receiver cannot reach the service that
validates keys it fails closed and returns the same
401. A sudden401across every service at once, with a key you have not changed, is far more likely to be this. Check$OIQ_ENDPOINT/healthfirst.
Config changes appear to do nothing
Config changes appear to do nothing
The collector reads its configuration only at startup. Restart it after any
edit, and confirm the file you edited is the one mounted into the process —
a bind mount pointing at a path that does not exist silently yields the
image’s default config rather than an error.
Next
Instrument your application
Zero-code setup per language.
Docker
For containerised workloads on this host.
Verify your data
Confirm it landed.