Monitoring nginx
nginx is recognised the moment the agent sees the process, and everything below starts on
its own within a minute. No stub_status, no exporter, no config edits on your side. The
agent reads the running configuration, follows the access log it finds there, and turns
every server block into a monitored site.
How nginx is recognised
The signed nginx definition matches a host that runs a process named nginx and listens on
port 80. Once matched, the agent runs nginx -v for the version and nginx -T for the
effective configuration, and derives from it:
- the main configuration file,
- every
access_loganderror_logpath in use (the real ones, including per-site logs under custom directories), - every
serverblock with itsserver_nameentries, listen ports, document root and PHP backend.
The configuration scan repeats every 15 minutes, the site sweep every 5 minutes, the log counters every 30 seconds. An nginx that is present but not running does not match, so a box that only has the package installed is left alone.
What is collected
Request rates. The agent tails the discovered access log from a saved offset (rotation is handled) and counts lines into three per-second rates: requests, 4xx responses and 5xx responses. Nothing about individual requests is stored; the lines stay on the host.
A liveness check on 127.0.0.1:80: the connection has to be accepted. Whether a page
answers with 200 or 404 is not the point here, that is the job of the per-site checks.
Sites. Each server block becomes a site with its own HTTP check through the Host
header, TLS certificate days-left and trust verdict, DNS liveness of the domain, a CDN
verdict (is the domain served from this host or from an edge in front of it), a domain
registration age and expiry where the registry publishes them, and a flag for a PHP
backend socket that does not exist. Per-site details live on
Websites and domains.
Facts shown on the host page: version, config file, log paths, and per site the document root, whether it runs WordPress, and which PHP minor version its pool uses.
| Signal | Metric |
|---|---|
| Requests per second | svc.nginx.req_rate |
| 4xx per second | svc.nginx.client_error_rate |
| 5xx per second | svc.nginx.server_error_rate |
| Per-site latency, certificate, DNS, domain | svc.nginx.vhost.* tagged by vhost |
Names, tags and units are in the metrics reference.
Alerts out of the box
| Rule | Fires when | Severity | Ships |
|---|---|---|---|
| Site down | every local probe of a site failed for 10 minutes | warning | on |
| Certificate expired / expiring | a site's certificate is past its end, or within 14 days of it | critical / warning | on |
| Origin certificate expired | the certificate is expired but the domain points at a CDN, so visitors see the edge certificate | warning | on |
| Domain does not resolve | the site's domain answers NXDOMAIN for 10 minutes | warning | on |
| Site has no PHP backend | the block points at a PHP socket that is missing for 5 minutes | warning | on |
| Domain expiring / expired | registration ends within 14 days, or has lapsed | warning / critical | on |
| Service floods error logs | 50 or more error lines in 15 minutes | warning | on |
| nginx serves 5xx at a high rate | more than one 5xx per second sustained 10 minutes | warning | off |
The 5xx-rate rule ships off because the rate that means trouble depends entirely on how much traffic the site gets; enable it per workspace once you know your baseline. Site down needs every probe in the window to fail, so a single slow response never raises it. The thresholds and the hysteresis of each rule are in the rules catalog.
Going deeper
- APM, layer 1. Where the kernel allows eBPF (virtual machines, bare metal, privileged containers), the agent measures request rate, error rate and latency percentiles on the wire, per port, with no change to nginx. Where it does not, the access-log rates above are the fallback. See APM: how it works.
- PHP sites behind nginx get method-level traces and CPU flame graphs from the PHP-FPM side, see Monitoring PHP-FPM.
- Logs. The error log ships by default at notice level and above; the access log is
collected only when you switch that service to full depth in the console. Request lines
that are the client's fault (a 404 for a missing script, a
403from an allow rule) are filed at notice, so they do not count as server errors. See Logs. - Outside-in checks on the same sites from our vantage points, see Synthetics.
When a path is not where nginx says it is
The agent trusts nginx -T, which is almost always right. If a log is written elsewhere
(for example by a wrapper that rewrites paths), set the location yourself and it takes
precedence over the discovered one:
sudo wakora --set nginx.access-log=/www/logs/access.log
Keys and the full mechanism are in Agent configuration.
Limitations
- Rates come from the access log. A site with
access_log offproduces none, and the agent says so on the check rather than inventing zeros. - Only the first
server_nameof a block is probed; the other names are recorded as aliases and are not checked individually. - Blocks that only redirect (a
return 301bouncer) and catch-all blocks (_, a bare IP,localhost) are recorded but not probed: probing them would fail by design. - The site probe runs on the host against
127.0.0.1, so it cannot see a CDN, a firewall or a broken DNS record between your visitors and the box. That view comes from synthetics. - A site behind a CDN is judged by its origin certificate. When the domain points away from the host, an expired origin certificate is a warning, not a critical.
Related
- Websites and domains
- Monitoring PHP-FPM and Monitoring Apache
- WordPress monitoring and monitoring for hosting providers on the main site