Skip to content

Info

License: Free — part of the universal collection tier.

Docker

The docker probe monitors Docker containers via the Docker Engine API Unix socket, reporting per-container CPU, memory, network I/O, block I/O and running state. No external client library is required.

Quick start

# probes.d/10-docker.yaml — each file under probes.d/ is a YAML array of probes
- name: docker
  type: docker

The probe connects to the local Docker Engine on whichever transport the platform offers, with no parameter needed for a local setup:

Platform Default address Transport
Linux, macOS /var/run/docker.sock Unix socket
Windows npipe://./pipe/docker_engine named pipe

Docker Engine and Docker Desktop on Windows expose the API over a named pipe rather than a socket, which is why the default differs. Set socket_path to override it; a Windows pipe may be written npipe://./pipe/<name> or \\.\pipe\<name>.

Parameters

Parameter Must set Default Description
socket_path No - Engine socket; /var/run/docker.sock on Unix, npipe://./pipe/docker_engine on Windows by default
interval No 60 Seconds between collections
timeout No 10 Engine request timeout in seconds
include No - Container name patterns to keep; empty means all. Example: web-*
exclude No - Container name patterns to drop; wins over include

include and exclude are shell-style globs (web-*, db?) matched against the container's primary name.

Metrics

Metric Unit Description
senhub.docker.up 1 1 when the container is in the running state, 0 otherwise
container.restarts {restart} Number of times the container has been restarted
container.cpu.usage.total s Total CPU time consumed by the container (monotonic)
container.memory.usage By Current memory usage (RSS)
senhub.docker.memory.limit By Memory limit configured for the container
container.network.io.usage.rx_bytes By Bytes received on all network interfaces (monotonic)
container.network.io.usage.tx_bytes By Bytes sent on all network interfaces (monotonic)
container.blockio.io_service_bytes_recursive.read By Bytes read from block devices (monotonic)
container.blockio.io_service_bytes_recursive.write By Bytes written to block devices (monotonic)

Each metric is tagged with container_name and container_id; CPU metrics are additionally tagged with core.

What a Windows container reports

The engine answers a different shape on Windows, so a few channels come from different fields there and a few are absent:

Channel Linux Windows
Memory usage cgroup usage, minus the page cache for the working set private working set, plus the commit charge and its peak
Memory limit the cgroup limit not reported by the engine, so zero
CPU percentage container time against host time container time against the wall time between two samples, times the processors the container may use
Block I/O blkio counters per device the storage counters the engine reports for the container
Per-core CPU, throttling, page-cache breakdown reported not reported by the engine

A value the engine does not send is left at zero rather than guessed.

Running without access to the Docker socket

/var/run/docker.sock is root:docker mode 0660, so an agent running as the unprivileged senhub service user cannot open it. The usual remedy is to add that user to the docker group — and it is worth knowing what that grants: anyone who can reach the socket can start a container that mounts the host filesystem, so docker group membership is root on the host by another route. It is a decision to make deliberately, which is why the installer never makes it for you.

The probe does not require it. When the socket is unavailable it reads container counters straight from cgroups, which are world-readable:

Available from cgroups Needs the socket
container.cpu.* container.network.*
container.memory.* container.restarts
container.blockio.* container name, image, labels, state
container.pids.count the container entity in topology

That is 26 of the probe's 31 metrics with no group, no capability and no path to root. Containers are identified by id alone in this mode — a name guessed from a cgroup path would be wrong the moment someone renamed a container, and wrong identity is worse than none.

Per-container network counters are the real loss. They live in the container's network namespace rather than its cgroup, so there is no unprivileged file to read; they are absent rather than reported as zero.

senhub.docker.source tells you which mode a cycle used, socket or cgroup. Alert on it if you rely on the socket-only metrics — the two modes do not carry the same fields, and a host that quietly fell back would otherwise look like a host whose containers stopped using the network.

Limitations: the fallback reads cgroup v2 only. On a cgroup v1 host the probe still needs the socket, and says so in the log rather than publishing half the picture.

Keeping the metadata without granting host root

A docker socket proxy — a small HAProxy in front of the socket that allow-lists only the endpoints the agent reads and returns 403 for everything else — gives the container names and labels back without granting container creation. The probe uses exactly two read-only endpoints, GET /containers/json and GET /containers/{id}/stats, so the allow-list is short. Tecnativa/docker-socket-proxy is the usual implementation.

Operational notes

  • The agent must have read access to /var/run/docker.sock. On Linux, add the agent user to the docker group or run as root.
  • All containers visible to the socket are monitored; use Docker labels or external filtering to restrict if needed. In cgroup mode every container with a cgroup is reported, and include/exclude cannot filter by name because no name is available.
  • Stopped containers emit senhub.docker.up=0 without CPU/memory metrics.

Metric reference

Every metric this probe can emit. Metric is the OpenTelemetry name the OTLP, Prometheus and Zabbix outputs derive theirs from. Name is what a Nagios check and the API metrics= filter match. PRTG channel is the label PRTG shows, placeholders filled from the series' tags.

Metric Name PRTG channel Unit Description
senhub.docker.source senhub.docker.source Docker Metric Source ({source}) # one-hot over socket / cgroup — which source produced this cycle. The cgroup fallback works without the docker group but reports no per-container network counters, restart counts or container names
senhub.docker.up senhub.docker.up Docker {container_name} Up # 1 when the container is running, 0 otherwise
container.restarts container.restarts Docker {container_name} Restart Count # Number of times the container has been restarted
container.cpu.usage.total container.cpu.usage.total Docker {container_name} CPU Usage ns Cumulative CPU time consumed by the container
container.cpu.usage.kernelmode container.cpu.usage.kernelmode Docker {container_name} CPU Kernel Mode ns Cumulative CPU time consumed in kernel mode by the container
container.cpu.usage.usermode container.cpu.usage.usermode Docker {container_name} CPU User Mode ns Cumulative CPU time consumed in user mode by the container
senhub.docker.cpu.system senhub.docker.cpu.system Docker {container_name} CPU System Time ns System CPU time since the container started (used to compute CPU %)
senhub.docker.cpu.online senhub.docker.cpu.online Docker {container_name} CPU Online # Number of online CPUs available to the container
senhub.docker.cpu.percent senhub.docker.cpu.percent Docker {container_name} CPU % % CPU utilisation percentage (same formula as docker stats)
container.cpu.usage.percpu container.cpu.usage.percpu Docker {container_name} CPU Core {core} ns Cumulative CPU time consumed by the container on a specific core (percpu_usage)
container.cpu.throttling_data.throttled_periods container.cpu.throttling_data.throttled_periods Docker {container_name} CPU Throttled Periods # Number of periods where the container was throttled (from throttling_data)
container.cpu.throttling_data.periods container.cpu.throttling_data.periods Docker {container_name} CPU Throttling Periods # Total number of CPU periods (from throttling_data.throttling_periods)
container.cpu.throttling_data.throttled_time container.cpu.throttling_data.throttled_time Docker {container_name} CPU Throttled Time ns Cumulative nanoseconds the container was throttled (from throttling_data)
container.memory.usage container.memory.usage Docker {container_name} Memory Usage B Current memory usage of the container (includes page cache)
senhub.docker.memory.limit senhub.docker.memory.limit Docker {container_name} Memory Limit B Memory limit configured for the container (0 = unlimited)
container.memory.rss container.memory.rss Docker {container_name} Memory RSS B Anonymous memory (RSS on cgroupsv1, anon on cgroupsv2)
container.memory.cache container.memory.cache Docker {container_name} Memory Cache B Page cache memory (cache on cgroupsv1, file on cgroupsv2)
container.memory.swap container.memory.swap Docker {container_name} Memory Swap B Swap memory usage
container.memory.working_set senhub.docker.memory.working_set Docker {container_name} Memory Working Set B Working set memory (usage minus page cache) — what docker stats reports as MEM USAGE
container.memory.anon container.memory.anon Docker {container_name} Memory Anonymous B Anonymous (non-file-backed) memory; uses rss key on cgroupsv1, anon on cgroupsv2
container.memory.mapped_file container.memory.mapped_file Docker {container_name} Memory Mapped File B Memory mapped to files (cgroupsv1 mapped_file; absent on cgroupsv2)
container.memory.pgfault container.memory.pgfault Docker {container_name} Memory Page Faults # Cumulative minor page faults (pgfault from memory_stats.stats)
container.memory.pgmajfault container.memory.pgmajfault Docker {container_name} Memory Major Page Faults # Cumulative major page faults requiring disk I/O (pgmajfault from memory_stats.stats)
container.memory.unevictable container.memory.unevictable Docker {container_name} Memory Unevictable B Memory that cannot be reclaimed (locked pages, mlocked regions)
container.memory.writeback container.memory.writeback Docker {container_name} Memory Writeback B Memory queued for write-back to disk
container.memory.hierarchical_memory_limit container.memory.hierarchical_memory_limit Docker {container_name} Memory Hierarchical Limit B Memory limit of the container's cgroup hierarchy (cgroupsv1 only)
container.memory.active_anon container.memory.active_anon Docker {container_name} Memory Active Anon B Recently-accessed anonymous memory in the active LRU list
container.memory.inactive_anon container.memory.inactive_anon Docker {container_name} Memory Inactive Anon B Less-recently-accessed anonymous memory in the inactive LRU list
container.memory.active_file container.memory.active_file Docker {container_name} Memory Active File B Recently-accessed file-backed memory in the active LRU list
container.memory.inactive_file container.memory.inactive_file Docker {container_name} Memory Inactive File B Less-recently-accessed file-backed memory in the inactive LRU list (used for working-set on cgroupsv2)
container.pids.count container.pids.count Docker {container_name} PID Count # Number of processes running inside the container
senhub.docker.pids.limit senhub.docker.pids.limit Docker {container_name} PID Limit # Maximum number of processes allowed in the container (0 = unlimited)
container.network.io.usage.tx_bytes container.network.io.usage.tx_bytes Docker {container_name} Network TX B Cumulative bytes transmitted across all network interfaces
container.network.io.usage.rx_bytes container.network.io.usage.rx_bytes Docker {container_name} Network RX B Cumulative bytes received across all network interfaces
senhub.docker.network.tx_packets senhub.docker.network.tx_packets Docker {container_name} Network TX Packets # Cumulative packets transmitted across all network interfaces
senhub.docker.network.rx_packets senhub.docker.network.rx_packets Docker {container_name} Network RX Packets # Cumulative packets received across all network interfaces
container.network.io.usage.tx_errors container.network.io.usage.tx_errors Docker {container_name} Network TX Errors # Cumulative transmit errors across all network interfaces
container.network.io.usage.rx_errors container.network.io.usage.rx_errors Docker {container_name} Network RX Errors # Cumulative receive errors across all network interfaces
senhub.docker.network.tx_dropped senhub.docker.network.tx_dropped Docker {container_name} Network TX Dropped # Cumulative transmitted packets dropped across all network interfaces
senhub.docker.network.rx_dropped senhub.docker.network.rx_dropped Docker {container_name} Network RX Dropped # Cumulative received packets dropped across all network interfaces
container.blockio.usage.total container.blockio.usage.total Docker {container_name} Block I/O B Cumulative block I/O bytes (read + write, or Total entry when present)
container.blockio.io_service_bytes_recursive.read container.blockio.io_service_bytes_recursive.read Docker {container_name} Block I/O Read B Cumulative block I/O read bytes
container.blockio.io_service_bytes_recursive.write container.blockio.io_service_bytes_recursive.write Docker {container_name} Block I/O Write B Cumulative block I/O write bytes
senhub.docker.blkio.service_time.total senhub.docker.blkio.service_time.total Docker {container_name} Block I/O Service Time ns Cumulative block I/O service time in nanoseconds (io_service_time_recursive Total; cgroupsv1 only)
senhub.docker.blkio.sectors.total senhub.docker.blkio.sectors.total Docker {container_name} Block I/O Sectors # Cumulative block I/O sectors transferred (io_sectors_recursive Total; cgroupsv1 only)