Skip to main content

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_log and error_log path in use (the real ones, including per-site logs under custom directories),
  • every server block with its server_name entries, 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.

SignalMetric
Requests per secondsvc.nginx.req_rate
4xx per secondsvc.nginx.client_error_rate
5xx per secondsvc.nginx.server_error_rate
Per-site latency, certificate, DNS, domainsvc.nginx.vhost.* tagged by vhost

Names, tags and units are in the metrics reference.

Alerts out of the box​

RuleFires whenSeverityShips
Site downevery local probe of a site failed for 10 minuteswarningon
Certificate expired / expiringa site's certificate is past its end, or within 14 days of itcritical / warningon
Origin certificate expiredthe certificate is expired but the domain points at a CDN, so visitors see the edge certificatewarningon
Domain does not resolvethe site's domain answers NXDOMAIN for 10 minuteswarningon
Site has no PHP backendthe block points at a PHP socket that is missing for 5 minuteswarningon
Domain expiring / expiredregistration ends within 14 days, or has lapsedwarning / criticalon
Service floods error logs50 or more error lines in 15 minuteswarningon
nginx serves 5xx at a high ratemore than one 5xx per second sustained 10 minuteswarningoff

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 403 from 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 off produces none, and the agent says so on the check rather than inventing zeros.
  • Only the first server_name of a block is probed; the other names are recorded as aliases and are not checked individually.
  • Blocks that only redirect (a return 301 bouncer) 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.