Skip to main content

Monitoring Docker

Docker is recognised by its daemon and read through the engine socket, with no Docker CLI involved and nothing to configure. Containers are reported per image rather than one by one: three containers of the same image are one monitored unit with a count, so a scaled service does not multiply your inventory. Their stdout and stderr ship as logs under the image name.

How Docker is recognised​

The signed Docker definition matches a host that runs the dockerd process. Every minute the probe talks to the Engine API over /var/run/docker.sock: it lists all containers (stopped ones included), reads the engine version, inspects each container for its restart count and health status, and takes one stats sample from every running container, eight at a time. The log definition runs every 30 seconds over the same socket.

Processes that run inside containers are filtered out of host discovery by their cgroup markers, so a database inside a container never matches the host-level definition for that database. Containers are this probe's domain. A containerised service that publishes a port can still be matched through that port on the host, which is how RabbitMQ, Kafka and NATS are picked up.

What is collected​

Grouping by image. Containers are grouped by the image reference Docker reports (nginx:alpine, postgres:16; an untagged image is grouped by the start of its digest). Each group appears in the host inventory as one entry with the container count, how many are running, and up to twenty container names.

Per group. Running containers, CPU as a sum of the running containers' percentages, memory in use (with the inactive file cache subtracted, the way docker stats reports it), cumulative network bytes in and out, cumulative block IO read and written, the summed restart count, and restarts over the last hour computed on the host from that counter. For groups whose image defines a healthcheck, the number of containers currently reporting unhealthy.

Host-wide. Containers total and running, and the number of image groups.

Facts shown on the host page: the Docker engine version.

SignalMetric
Containers total / runningsvc.docker.containers, svc.docker.containers_running
Image groupssvc.docker.services
Per-group countssvc.docker.group.containers, svc.docker.group.running tagged by image
Per-group CPU and memorysvc.docker.group.cpu_pct, svc.docker.group.mem_bytes
Per-group network and block IO (cumulative)svc.docker.group.net_rx_total, .net_tx_total, .blkio_read_total, .blkio_write_total
Restarts, cumulative and last hoursvc.docker.group.restarts, svc.docker.group.restarts_1h
Unhealthy containers (healthcheck groups only)svc.docker.group.unhealthy

Names, tags and units are in the metrics reference.

Logs. The stdout and stderr of running containers ship through the same socket, read from the point where the agent first saw each container (no backlog), with the short image name as the service (nginx for nginx:alpine). A line that carries a recognisable level keeps it; a stderr line without one is filed at notice, a stdout line at info. By default only notice and above ships, so you get stderr and explicit errors and warnings out of the box, and plain stdout only when you switch the service to full depth in the console. Up to fifty containers are followed. See Logs.

Alerts out of the box​

RuleFires whenSeverityShips
Container failing its healthcheckan image group reports at least one unhealthy container for 2 minuteswarningauto
Containers keep restartingan image group restarted 5 or more times within the last hour, held 5 minuteswarningon

The healthcheck rule arms itself the moment a group with a healthcheck exists, because only those groups emit the metric; a host without healthchecks never sees it. Restarts are judged over an hour on purpose: a deploy restarts a container once, a crash loop restarts it many times, and a per-minute rate would read one restart as sixty an hour and then nothing. The incident closes when the last hour holds no restart at all. Both rules open one incident per image, so a looping sidecar does not hide behind a healthy web tier. Thresholds and hysteresis are in the rules catalog.

Limitations​

  • Numbers are per image group, never per container. Two containers of the same image are not told apart, and different tags of one image are different groups.
  • Stopped containers count towards the group and its restart total but contribute no CPU, memory or IO.
  • Group CPU is a sum of container percentages, so it can exceed 100 on a multi-core host.
  • A group without a healthcheck has no unhealthy metric and no healthcheck alert; the restart rule still covers it.
  • Only the Docker engine is matched, and only through /var/run/docker.sock. Podman and a bare containerd have no dockerd process and do not match; a rootless Docker whose socket lives under a user's runtime directory matches, but the probe cannot reach the default socket and the check says so.
  • Log lines are attributed to the image, not to the individual container that wrote them.