Structured logging dictionary

This page describes the common entries of the Structured Logging component. Currently these backends are supported:

  • The default text based backend

  • The systemd-journal backend

  • The json backend

The default backend

The default backend uses a text representation of the key-value pairs. A line is constructed by appending all key-value pairs as key="value", separated by spaces. The output is written by passing the resulting text line to the standard error stream and also to syslog if --disable-syslog was not passed on the command-line.

An example line looks like this:

msg="Raised send buffer size" subsystem="setup" level="0" prio="Info" ts="2025-12-29T17:16:17+0100" frontend.address="127.0.0.1:8053" network.send_buffer_size="4194304
  • Key names are not quoted.

  • Values are quoted with double quotes.

  • If a value contains a double quote, it is escaped with a backslash.

  • Backslashes in the value are escaped by prepending a backslash.

The following keys are always present:

Key

Type

Example

Remarks

msg

string

"Raised send buffer size"

Value is the same for all instances of this log entry, together with subsystem it uniquely identifies the log message.

subsystem

string

"setup"

Uniquely identifies the log entry together with the value of msg.

level

number

"0"

The detail level of the log entry. Not actively used currently.

prio

enum

"Notice"

One of Alert=1, Critical=2, Error=3, Warning=4, Notice=5, Info=6, Debug=7.

ts

number

"1697614303.039"

Number of seconds since the Unix epoch, including fractional part.

A log entry can also have zero or more additional key-value pairs. We tried to adhere to OpenTelemetry’s general attributes when possible, or more specific ones like for example dns attributes or http attributes for DNS over HTTPS.

Common keys are:

Key

Type

Example

Remarks

error

string

"No such file or directory"

An error cause.

address

ip address:port

"[::]:5301"

An IP: port combination.

addresses

list of subnets

"127.0.0.0/8 ::ffff:0:0/96"

A list of subnets, space separated.

client.address

ip address:port

"[2001:db8::1]:1234"

Address of the DNS client.

backend.address

ip address:port

"[2001:db8::2]:53"

Address of the downstream backend.

backend.name

string

"my-backend"

Name of the downstream backend, if any.

backend.protocol

string

"DoT"

Protocol used to send DNS queries to the downstream backend.

destination.address

ip address:port

"192.0.2.42:53"

Destination address of a packet (may be more specific than frontend.address, or be the next hop and differ from client.address when the proxy protocol is being used, for example).

dns.question.class

unsigned integer

1

The DNS query class.

dns.question.id

unsigned integer

42

The DNS query ID.

dns.question.name

DNS name

"example.com"

The DNS query name.

dns.question.real_time_sec

integer

1767095038

The time this query was received, as the number of seconds since EPOCH.

dns.question.real_time_nsec

integer

23

Additional nano-seconds for dns.question.real_time_sec, for extra precision.

dns.question.size

unsigned integer

42

Size of the DNS query packet, in bytes.

dns.question.type

unsigned integer

28

The DNS query type.

dns.response.class

unsigned integer

1

The DNS response class.

dns.response.id

unsigned integer

42

The DNS response ID.

dns.response.latency_us

float

180.63

The latency between the query and the response, in microseconds.

dns.response.name

DNS name

"example.com"

The DNS response name.

dns.response.rcode

DNS Response Code

"No Error"

DNS response code

dns.response.size

unsigned integer

42

Size of the DNS response packet, in bytes.

dns.response.type

unsigned integer

28

The DNS response type.

frontend.address

ip address:port

"[::]:53"

Address this frontend is listening on.

frontend.protocol

string

"DoQ"

Protocol this frontend is accepting DNS queries over.

http.method

string

"GET"

HTTP/2 query method for DoH.

http.path

string

"/dns-query"

HTTP/2 query path for DoH.

http.response.status_code

HTTP status code

"200"

HTTP/2 response code for DoH.

http.stream_id

HTTP stream ID

"4242"

HTTP/2 stream identifier for DoH.

network.local.address

string

"192.0.2.2:53"

Local address and port DNSdist is listening on (webserver, console, …).

network.peer.address

string

"192.0.2.2:53"

Peer address of the network connection (may differ from client.address when the proxy protocol is used, for example).

path

filesystem path

"tmp/api-dir/apizones"

pool

string

"my-pool"

Downstream backends pool name.

protocol

string

"udp"

The systemd-journal backend

The systemd-journal structured logging backend uses mostly the same keys and values as the default backend, with the exceptions:

  • keys are capitalized as required for systemd-journal.

  • msg is translated to MESSAGE.

  • prio is translated to PRIORITY.

  • ts is translated to TIMESTAMP.

  • If the original key is in a list of keys special to systemd-journal, it is capitalized and prepended by PDNS_. The list of special keys is: message, message_id, priority, code_file, code_line, code_func, errno, invocation_id, user_invocation_id, syslog_facility, syslog_identifier, syslog_pid, syslog_timestamp, syslog_raw, documentation, tid, unit, user_unit, object_pid.

To use this logging backend, add the --structured-logging-backend systemd-journal to the command line in the systemd unit file.

To query the log, use a command similar to:

# journalctl -r -n 1 -o json-pretty -u dnsdist.service

The json backend

The json structured logging backend uses the same keys and values as the default backend. An example of a log object:

{"level": "0", "msg": "Adding TCP worker thread to handle TCP connections from clients", "priority": "6", "ts": "2025-12-29T17:20:20+0100"}

All values are represented as strings.

The JSON log objects are written to the standard error stream.