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.
| Signal | Metric |
|---|---|
| Containers total / running | svc.docker.containers, svc.docker.containers_running |
| Image groups | svc.docker.services |
| Per-group counts | svc.docker.group.containers, svc.docker.group.running tagged by image |
| Per-group CPU and memory | svc.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 hour | svc.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
| Rule | Fires when | Severity | Ships |
|---|---|---|---|
| Container failing its healthcheck | an image group reports at least one unhealthy container for 2 minutes | warning | auto |
| Containers keep restarting | an image group restarted 5 or more times within the last hour, held 5 minutes | warning | on |
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 nodockerdprocess 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.
Related
- Monitoring Kubernetes for container workloads scheduled by a cluster
- Running the agent as a container when the host itself is not yours to install on
- Monitoring RabbitMQ and Monitoring Kafka, typical containerised services matched by their published port
- Features on the main site