Docker container metrics with OpenTelemetry
The OpenTelemetry Collector’s docker_stats receiver queries the local Docker daemon’s stats API and emits per-container CPU, memory, network, and block I/O metrics. It reaches the daemon through the Docker socket, so the socket must be readable by the Collector.
Prerequisites
Section titled “Prerequisites”- A host running Docker Engine.
- Read access to the Docker socket (
/var/run/docker.sock). - Your Osuite ingest endpoint and token.
Set up the Collector
Section titled “Set up the Collector”Save the config below as config.yaml. The docker_stats receiver is wired into the metrics pipeline, and resourcedetection attaches host identity to every container metric.
receivers: docker_stats: endpoint: unix:///var/run/docker.sock collection_interval: 30s
processors: resourcedetection: detectors: [env, system] system: hostname_sources: [os] batch:
exporters: otlp/osuite: endpoint: ingest.<region>.osuite.io:443 headers: x-osuite-ingest-token: <your-ingest-token>
service: pipelines: metrics: receivers: [docker_stats] processors: [resourcedetection, batch] exporters: [otlp/osuite]Then run the Collector. Choose the deployment that matches your setup — both mount or grant access to the same socket.
Install the contrib Collector as a systemd service (see Linux host monitoring for the package install), place the config at /etc/otelcol-contrib/config.yaml, and grant the service user access to the Docker socket:
sudo usermod -aG docker otelcol-contribsudo systemctl restart otelcol-contribThe packaged service runs as the otelcol-contrib user, which must belong to the docker group to read /var/run/docker.sock.
Run the Collector as a container. The socket mount is required — without it the receiver cannot reach the daemon:
services: otelcol: image: otel/opentelemetry-collector-contrib:0.156.0 volumes: - ./config.yaml:/etc/otelcol-contrib/config.yaml - /var/run/docker.sock:/var/run/docker.sock group_add: - "999" # must equal the host's docker group idFind the host’s Docker group id with getent group docker | cut -d: -f3 and set group_add to match. The Collector image runs as a non-root user, so it needs this supplementary group to read the mounted socket.
Validate
Section titled “Validate”Confirm the Collector started without socket errors:
docker logs otelcol 2>&1 | grep -i docker_statsA permission error such as permission denied while trying to connect to the Docker daemon socket means the socket is mounted but not readable — fix the group membership above.
Verify in Osuite
Section titled “Verify in Osuite”What you should see
Container metrics arrive within a minute, labelled by container.name and container.image.name, emitting CPU, memory, network, and block I/O metrics.
Data collected
Section titled “Data collected”The docker_stats receiver emits container.* metrics, tagged with resource attributes container.id, container.name, and container.image.name. Default-enabled metrics include:
| Metric | Description |
|---|---|
container.cpu.utilization | Percentage of host CPU used by the container. |
container.memory.usage.total | Total memory used by the container, in bytes. |
container.memory.percent | Percentage of the container’s memory limit in use. |
container.network.io.usage.rx_bytes | Bytes received over the network. |
container.network.io.usage.tx_bytes | Bytes transmitted over the network. |
container.blockio.io_service_bytes_recursive | Bytes read from and written to block devices. |
Additional metrics (per-CPU usage, memory breakdowns, PIDs) are available but disabled by default; enable them under a metrics: block in the receiver config. See the receiver reference for the full list.
Troubleshooting
Section titled “Troubleshooting”permission deniedon the socket — the Collector reached the socket but cannot read it. On a host service, add the service user to thedockergroup; in a container, setgroup_add(or--group-add) to the host’s Docker group id.- No container metrics, no error — the socket is not reachable. On a host, confirm the
endpointpath; in a container, confirm the-v /var/run/docker.sock:/var/run/docker.sockmount is present. - Expecting container logs here —
docker_statsdoes not collect logs. Use Collect Docker logs.
No data in Osuite after a few minutes? Work through these checks.
- Endpoint — confirm the exporter targets exactly
ingest.<region>.osuite.io:443for your region, over TLS. - Token — confirm the ingest header carries a valid
<your-ingest-token>and has not been rotated. - Pipeline — confirm the signal you expect (traces, logs, or metrics) is wired into an active pipeline with the
otlp/osuiteexporter attached. - Export errors — check the application or Collector logs for OTLP export failures (auth, DNS, TLS, connection refused).
- Network — confirm the host has outbound access to the ingest endpoint on port
443. - Timing — allow up to a minute for the first data to appear before assuming a failure.
Still stuck? Ask the Investigation Agent or contact support.
Next steps
Section titled “Next steps”- Collect Docker logs — ship container log output
- Linux host monitoring — host-level metrics for the same machine
- Kubernetes monitoring — container metrics at cluster scale
- Dashboards — build container dashboards