Add opt-in JSON logging with structured DNS query fields (#8553)

* plugin/pkg/log: add opt-in JSON logging backend

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>

* plugin/log: emit typed query records in JSON mode

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>

* coremain: expose process-wide JSON logging

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>

---------

Signed-off-by: houyuwushang <liuluoqianqiu@outlook.com>
This commit is contained in:
houyuwushang
2026-09-17 08:50:39 +08:00
committed by GitHub
parent 84a93a0b89
commit b93e449b2f
20 changed files with 1064 additions and 22 deletions

View File

@@ -108,6 +108,32 @@ $ dig @127.0.0.1 google.com
## Examples
### JSON Logging
Start CoreDNS with `-log-format=json` to emit operational logs as single-line JSON.
The default `-log-format=text` retains the existing text output. The format applies
to the whole process, including all server blocks, and persists across Corefile
reloads. Query logging still requires the `log` plugin.
```sh
./coredns -conf Corefile -log-format=json
```
Records contain `time` (RFC3339 with fractional seconds), `level` (`DEBUG`, `INFO`,
`WARN`, `ERROR`, or `FATAL`), and `msg`. Named plugin loggers also include `plugin`.
Messages, including embedded newlines and DNS escapes, are JSON-encoded rather
than concatenated into JSON templates. Debug output still requires `debug`.
See the [log plugin](plugin/log/README.md#json-output) for typed query fields.
The standard library's default logger (including Caddy's lifecycle messages) is
routed through the same backend at `INFO` level; its original message is retained
without guessing severity or fields from text. Independently configured third-party
loggers, direct stdout/stderr writes, and Go runtime diagnostics are not intercepted.
Command-line help, flag parsing errors, `-version`, and `-plugins` remain human-readable.
Normal startup, Corefile errors, and query/error plugin logs use the selected format.
### Querying CoreDNS
When starting CoreDNS without any configuration, it loads the
[*whoami*](https://coredns.io/plugins/whoami) and [*log*](https://coredns.io/plugins/log) plugins
and starts listening on port 53 (override with `-dns.port`), it should show the following: