When we decided Opsot should require zero configuration to monitor PM2 and Docker, we had to figure out exactly how to discover and interface with these systems at the OS level.
PM2 Discovery
PM2 runs a daemon that manages Node.js processes and exposes a Unix domain socket at ~/.pm2/rpc.sock. The agent checks for this socket at startup and at regular intervals. When detected, it connects and queries the process list, receiving a JSON payload with every PM2 process: name, pid, status, memory, CPU, uptime, and restart count.
We re-query every 5 seconds — near-real-time process status updates without overwhelming the PM2 daemon. State changes like a crash and restart appear in the dashboard within seconds.
Docker Discovery
Docker exposes a Unix socket at /var/run/docker.sock. We connect and call the Docker Engine API over HTTP (Unix socket transport). The key endpoints:
GET /containers/json— list running containersGET /containers/{id}/stats?stream=true— streaming per-container resource statsGET /events?type=container— real-time container lifecycle events
For each running container we open a streaming stats connection. Docker sends a JSON blob every second containing CPU usage, memory, network I/O, and block I/O — all forwarded to our platform in real time.
Permissions
The agent needs read access to both sockets. For Docker, the agent's user must be in the docker group (recommended) or the agent can run as root. For PM2, the agent must run as the same user who started the PM2 daemon.