Monitoring PowerDNS
PowerDNS Authoritative Server is recognised by its pdns_server process and read through
pdns_control, the same tool you use on the command line. No API, no key, nothing to
enable: a package install is measured the moment the agent sees the process. A second
definition covers PowerDNS running in a container, where the process is hidden from the
host and the only door is the REST API behind the published web server port.
How PowerDNS is recognised
Two signed definitions carry the same service name, so a host never ends up with two PowerDNS entries. Which one activates depends on where the daemon runs.
Native install. The definition matches a host running a process named pdns_server.
Every 60 seconds the agent checks that something answers on 127.0.0.1:53 over TCP and runs
pdns_control show '*', which prints every counter the server keeps in one line. Every 15
minutes it runs pdns_control version and records the version as a fact. pdns_control
talks to the daemon over its local control socket; it needs no API and no credential. The
agent runs it from its allow-list of binaries, never through a shell. This path needs agent
release r329 or newer: an older agent skips the definition and reports why in its log.
Container. A PowerDNS container publishes its web server port, and that listener is what
the host agent can see, so the second definition matches a TCP listener on port 8081, the
default webserver-port. Every 60 seconds the agent calls
http://127.0.0.1:8081/api/v1/servers/localhost/statistics with the API key in the
X-API-Key header and parses five counters out of the answer. For the call to succeed the
container must run with api=yes, an api-key, and the web server listening on 8081.
What is collected
Queries and answers. UDP and TCP queries received and answers sent, as totals since the
daemon started, plus svc.powerdns.query_rate, the UDP query rate in queries per second
that the agent derives from the total between two readings.
Trouble. SERVFAIL answers, packets that could not be parsed, queries that timed out in
the backend, and packets dropped because the server was overloaded. Each comes as a total
and as a per-minute rate derived on the agent, and SERVFAIL also as a share of all
queries in percent, so a server answering one query a day and failing it does not look like
one failing half its traffic. The rates and the share are what the rules watch: a total
climbs forever and says nothing about now.
Caches. Hits and misses of the query cache (backend answers) and of the packet cache (whole answers). Hits divided by hits plus misses is the hit rate of each cache.
Health. The number of queries waiting in the backend queue, open TCP connections, the average time a packet spends inside PowerDNS in microseconds, and the daemon's uptime.
The native definition records one fact, the server version from pdns_control version. The
container definition records no facts and covers only the five counters marked below.
| Signal | Metric | Container path |
|---|---|---|
| UDP queries / answers, total | svc.powerdns.udp_queries, svc.powerdns.udp_answers | yes |
| TCP queries / answers, total | svc.powerdns.tcp_queries, svc.powerdns.tcp_answers | |
| UDP queries per second | svc.powerdns.query_rate | |
| SERVFAIL answers, total and per minute | svc.powerdns.servfail_packets, svc.powerdns.servfail_rate | total only |
| SERVFAIL share of all queries, percent | svc.powerdns.servfail_pct | |
| Corrupt packets, total and per minute | svc.powerdns.corrupt_packets, svc.powerdns.corrupt_rate | total only |
| Backend timeouts, total and per minute | svc.powerdns.timedout_packets, svc.powerdns.timedout_rate | |
| Overload drops, total and per minute | svc.powerdns.overload_drops, svc.powerdns.overload_drop_rate | |
| Query cache hits / misses | svc.powerdns.query_cache_hit, svc.powerdns.query_cache_miss | hits only |
| Packet cache hits / misses | svc.powerdns.packetcache_hit, svc.powerdns.packetcache_miss | |
| Queries waiting in the backend queue | svc.powerdns.qsize_q | |
| Open TCP connections | svc.powerdns.open_tcp_connections | |
| Average time inside PowerDNS, microseconds | svc.powerdns.latency_us | |
| Daemon uptime, seconds | svc.powerdns.uptime_sec |
Names, tags and units are in the metrics reference.
Alerts out of the box
| Rule | Fires when | Severity | Ships |
|---|---|---|---|
| PowerDNS answers SERVFAIL to many queries | 20% or more of queries answered SERVFAIL for 10 minutes | warning | auto |
| PowerDNS backend is not answering | 30 or more backend timeouts a minute for 5 minutes | warning | auto |
| PowerDNS is dropping queries under load | any overload drop within a minute, sustained 5 minutes | warning | auto |
All three arm themselves on the native path, where the rates exist, and watch rates or the
share, never the totals, so they fire while the trouble lasts and clear when it stops. The
SERVFAIL rule is a share rather than a count on purpose: a few SERVFAIL answers are
normal on any public authoritative server (queries for zones it does not hold), one in five
is a backend or a zone that is broken. Timeouts are the backend database not answering;
overload drops mean the server shed queries, which on an authoritative server should never
happen at all, hence the threshold at the first one. Any other metric above can drive a
custom rule under Alerting, rules. On the container path only totals
exist, so a rule there needs a total that should stay at zero, such as corrupt packets.
Thresholds and hysteresis are in the rules catalog.
Credentials
The native path needs none. pdns_control reads the daemon's control socket, which the
agent can open as root, and nothing leaves the host but the numbers.
The container path needs the API key, stored once on the host under the name the definition expects:
sudo wakora secret set pdns-api
Enter the key at the password prompt; an API key has no user part. It is stored encrypted
on the host, bound to that machine, and never sent anywhere: the agent reads it locally and
puts it in the X-API-Key header of the local API call. Until the secret exists, the check
states that pdns-api is not set on the host and names this command. See
Secrets stay local.
Limitations
- Only the Authoritative Server is covered. The Recursor is a different daemon
(
pdns_recursor) with different counters and is not recognised. - The native path expects
pdns_controlto find the daemon the way it does on the command line, through the default configuration. A daemon started with a non-defaultconfig-dirorconfig-namefails the counters check with the tool's own message. - Container recognition is by port 8081 only. A web server published on another port, or not published at all, means a containerised PowerDNS is not recognised.
- The container path has no check on port 53, no version fact, no rate metrics and therefore no built-in rule: the API call is the whole probe.
- Per-zone statistics and backend latency by backend are not collected.
- No log shipping definition exists for PowerDNS.
Related
- Monitoring BIND, Monitoring Unbound
- Websites and domains for the DNS liveness of the sites you host
- Monitoring for hosting providers on the main site