Skip to content

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.

  • A host running Docker Engine.
  • Read access to the Docker socket (/var/run/docker.sock).
  • Your Osuite ingest endpoint and token.

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:

Terminal window
sudo usermod -aG docker otelcol-contrib
sudo systemctl restart otelcol-contrib

The packaged service runs as the otelcol-contrib user, which must belong to the docker group to read /var/run/docker.sock.

Confirm the Collector started without socket errors:

Terminal window
docker logs otelcol 2>&1 | grep -i docker_stats

A 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.

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.

The docker_stats receiver emits container.* metrics, tagged with resource attributes container.id, container.name, and container.image.name. Default-enabled metrics include:

MetricDescription
container.cpu.utilizationPercentage of host CPU used by the container.
container.memory.usage.totalTotal memory used by the container, in bytes.
container.memory.percentPercentage of the container’s memory limit in use.
container.network.io.usage.rx_bytesBytes received over the network.
container.network.io.usage.tx_bytesBytes transmitted over the network.
container.blockio.io_service_bytes_recursiveBytes 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.

  • permission denied on the socket — the Collector reached the socket but cannot read it. On a host service, add the service user to the docker group; in a container, set group_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 endpoint path; in a container, confirm the -v /var/run/docker.sock:/var/run/docker.sock mount is present.
  • Expecting container logs heredocker_stats does 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:443 for 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/osuite exporter 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.