Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Logging and metrics

DNSY has three sources of operational data: process logs, the query log with its statistics, and the health endpoints.

Process logs

Logs go to stderr through tracing. [logging] level selects trace, debug, info, warn or error; format = "json" writes one JSON object per line for a log shipper, pretty is for terminals. Tokens, Authorization headers, cookies, DoH path tokens, passwords and the DNSSEC key passphrase are never logged. A reload that fails (SIGHUP, certificate or zone change) keeps the previous state and logs the reason at warn.

Under systemd the logs are in the journal (journalctl -u dnsy); in a container they are the container’s stderr.

Query log and statistics

Every answered query becomes one event: time, client, transport, principal, name, type, response code, answer source, DNSSEC status and latency. Events are written to SQLite in batches and kept for [querylog] retention_days; redact_client_ip stores only the client network, sample keeps one raw row in N queries and max_size_mb caps the database. See Query log and stats for the fields, rollups and the filter syntax.

The statistics endpoints are the metrics interface:

EndpointWhat it gives
GET /api/v1/stats/summarytotals, blocked ratio, cache hit ratio, answers by source and DNSSEC status, latency
GET /api/v1/stats/timeseriescounts per minute or hour bucket
GET /api/v1/stats/top-domains, top-blocked, top-clientsranked lists
GET /api/v1/cachelive cache counters
GET /api/v1/dnssec/statusvalidation mode, trusted clock, secure and bogus counts of the last 24 hours
GET /api/v1/upstream-groups/{name}/healthper-upstream health
GET /api/v1/querylog/streamlive tail as server-sent events
curl -s -H "Authorization: Bearer $DNSY_TOKEN" http://127.0.0.1:5380/api/v1/stats/summary | jq

There is no Prometheus /metrics endpoint in this release. Poll the summary endpoint (it is cheap: it reads precomputed rollups) or scrape the JSON with an exporter of your own.

Health

GET /healthz is liveness (the process runs). GET /readyz is readiness: 200 when the database answers and every DNSSEC zone can be signed, 503 otherwise (dnssec_signing_failed when a zone’s keys cannot be opened), and a warnings list such as querylog_disk_full (the query-log writer hit SQLITE_FULL; clears after the next successful write) or dnssec_clock_untrusted while the system clock is earlier than the build time. Neither needs credentials.

What to alert on

  • /readyz not 200.
  • Cache hit ratio dropping, or upstream health below the number of configured upstreams.
  • bogus answers rising in /dnssec/status (a broken signed zone or a clock problem).
  • Query log events dropped (the writer’s counter) under load.