COREDNS-METRICS(7)

๐Ÿ“ฆ
version 1.15.0 ยท 3 versions
, in opensuse-leap 16.0

๐ŸŽ€ COREDNS-METRICS(7) โ€” the prometheus plugin, explained ๐Ÿ’…

okay so bestie, real talk: this is the manpage for the prometheus plugin, and its whole personality is enabling Prometheus โŸจhttps://prometheus.io/โŸฉ metrics. That's the NAME section, we're done, slay. โœจ


๐ŸŒธ DESCRIPTION ๐ŸŒธ

So with prometheus you export metrics from CoreDNS and, like, from any plugin that happens to have them. The default hangout spot for the metrics is localhost:9153, and the metrics path is fixed to /metrics โ€” no negotiating, it's giving "my way or the highway". ๐Ÿ›ฃ๏ธ

On top of the default Go metrics that the Prometheus Go client โŸจhttps://prometheus.io/docs/guides/go-application/โŸฉ exports on its own, you also get these absolute icons: ๐Ÿ‘‘

  • coredns_build_info{version, revision, goversion} โ€” info about CoreDNS itself. the lore.
  • coredns_panics_total{} โ€” total number of panics. screaming, crying, throwing up counter ๐Ÿ˜ญ
  • coredns_dns_requests_total{server, zone, view, proto, family, type} โ€” total query count.
  • coredns_dns_request_duration_seconds{server, zone, view, type} โ€” duration to process each query.
  • coredns_dns_request_size_bytes{server, zone, view, proto} โ€” size of the request in bytes. Uses the original size before any plugin rewrites โ€” pre-glow-up measurements only, bestie.
  • coredns_dns_do_requests_total{server, view, zone} โ€” queries that have the DO bit set.
  • coredns_dns_response_size_bytes{server, zone, view, proto} โ€” response size in bytes.
  • coredns_dns_responses_total{server, zone, view, rcode, plugin} โ€” response per zone, rcode and plugin.
  • coredns_dns_https_responses_total{server, status} โ€” responses per server and http status code.
  • coredns_dns_quic_responses_total{server, status} โ€” responses per server and QUIC application code.
  • coredns_plugin_enabled{server, zone, view, name} โ€” indicates whether a plugin is enabled on per server, zone and view basis.

Almost every counter carries a zone label, and that's just the zonename used for the request/response. ๐Ÿ—บ๏ธ

โœจ the extra labels, decoded โœจ

  • server identifies the server responsible for the request. It's a string formatted as the server's listening address: <scheme>://[<bind>]:<port>. So for a "normal" DNS server this is dns://:53. And if you're using the bind plugin, an IP address gets included too, e.g. dns://127.0.0.53:53. ๐Ÿซถ
  • proto holds the transport of the response ("udp" or "tcp").
  • family is the address family of the transport (1 = IP (IP version 4), 2 = IP6 (IP version 6)).
  • type holds the query type. It covers the most common types (A, AAAA, MX, SOA, CNAME, PTR, TXT, NS, SRV, DS, DNSKEY, RRSIG, NSEC, NSEC3, HTTPS, IXFR, AXFR and ANY) plus "other", which is the group-chat where all the remaining types get lumped together. ๐Ÿ™ˆ
  • status holds the https status code. possible values are:
    • 200 โ€” request is processed,
    • 404 โ€” request has been rejected on validation,
    • 400 โ€” request to dns message conversion failed,
    • 500 โ€” processing ended up with no response.
  • plugin holds the name of the plugin that made the write to the client. And if the server did the write (on error for instance), the value is empty. ghosted. ๐Ÿ’€

If monitoring is enabled, queries that do not enter the plugin chain get exported under the fake name "dropped" โ€” and note there's no closing dot on it, because this is never a valid domain name. it's a fake name, it's cosplaying, we love it.

Other plugins may export additional stats whenever the prometheus plugin is enabled โ€” those stats are documented in each plugin's own README, so go read those, iykyk. ๐Ÿ“š

๐Ÿšจ big one, bestie: this plugin can only be used once per Server Block. one. uno. don't push it.

๐Ÿ’– SYNTAX ๐Ÿ’–

prometheus [ADDRESS] {
    runtime_metrics
}

For each zone that you want to see metrics for. ๐ŸŽฏ

It optionally takes a bind address to which the metrics are exported; the default listens on localhost:9153. And again โ€” the metrics path is fixed to /metrics.

  • runtime_metrics โ€” exports the full Go runtime/metrics โŸจhttps://pkg.go.dev/runtime/metricsโŸฉ set, notably go_cpu_classes_* for CPU attribution (GC mark/assist/pause vs user code) and go_sched_latencies_seconds for goroutine scheduling delay. Adds roughly 100 scalars and 8 histograms. ๐Ÿงฎ
โš ๏ธ heads up: this is a process-wide latch โ€” enabling it in any server block enables it for all of them, and it stays enabled across reloads until restart. it's not a phase, it's a lifestyle. ๐Ÿ”’

๐Ÿฆ‹ EXAMPLES ๐Ÿฆ‹

Use an alternative listening address, like the main character you are:

. {
    prometheus localhost:9253
}

Or via an environment variable (this is supported throughout the Corefile): export PORT=9253, and then:

. {
    prometheus localhost:{$PORT}
}

look at that variable interpolation go. obsessed. โœจ


๐ŸŒˆ BUGS ๐ŸŒˆ (yes we have lore, unfortunately)

When reloading, the Prometheus handler is stopped before the new server instance is started. And if that new server fails to start? then the initial server instance is still available and DNS queries still get served, but the Prometheus handler stays down. ๐Ÿ˜ญ Prometheus will not reply to HTTP requests until a successful reload or a complete restart of CoreDNS. so basically it's sitting there like "no thoughts, head empty" until you fix it. ๐Ÿ”ฅ

Also: only the plugins that register as Handler are visible in coredns_plugin_enabled{server, zone, name}. As of today the plugins reload and bind will not be reported. they're lowkey invisible. ๐Ÿ™ˆ


and that's the whole page, bestie, you ate. ๐Ÿ’… this was CoreDNS โ€” October 2026 โ€” manual page COREDNS-METRICS(7). go forth and scrape responsibly. ๐Ÿ“๐Ÿงš๐Ÿ’œ

๐Ÿ“ฆ where this page comes from