Administration / Metrics & health
  1. Overview
  2. Metric event structure
  3. Syslog metrics event
    1. Format
    2. Single-target example
    3. Multi-target example
    4. Syslog parser pattern
  4. JSON metrics event
    1. Single-target example
    2. Multi-target example
  5. Field reference
    1. etwReader
    2. forwarder
    3. eventQueue
    4. eventsLost vs eventsDropped
  6. Windows Event Log
  7. Interpreting metrics
    1. Healthy steady state
    2. Abnormal states

Overview

DnsStream emits operational metrics through several channels. The first is the Windows Event Log, where DnsStream writes periodic summary entries covering ETW capture state, queue health, and per-connection forwarding metrics. The second is the configured forwarding pipeline itself - at the same interval, DnsStream emits a structured metrics event in the same format and to the same destination as DNS telemetry events, allowing SIEM-side dashboards and alerts to be driven by the same data stream. Both, one or none of the channels can be active.

# Send to the event forwarding pipeline
log-event metrics

# Send to the Windows Event Log
log-metrics-to-eventlog on

# Generate metrics events every 10 minutes
log-metrics-interval 600

Metric event structure

Each metrics event covers three subsystems, each reported as a distinct section:

Section Covers
etwReader The ETW session receiving DNS events from the Windows DNS Server service.
forwarder One block per configured forwarding target, reporting connection state and forwarding throughput.
eventQueue The in-memory ring buffer sitting between ETW capture and network forwarding.

These three sections map onto stages of the DnsStream data path - capture, buffer, forward - making it straightforward to identify which stage a problem is occurring in.

Syslog metrics event

Format

When log-event metrics is configured, DnsStream delivers a metrics event to the same forwarding target as DNS events. In syslog format, the payload is prefixed with metrics: to distinguish it from DNS query and response events, which use queries: .

The three sections appear in a fixed order - etwReader, then one forwarder block per forwarder target configured, then eventQueue - each enclosed in square brackets with space-separated key=value fields inside.

metrics: etwReader[...] forwarder[id=0 ...] forwarder[id=1 ...] eventQueue[...]

Single-target example

A deployment with one forwarding target:

Full message - with log-syslog-header rfc5424 set:

<30>1 2026-03-24T10:00:00Z windows2025 dnsstream 6824 - - metrics: etwReader[numberOfBuffers=16 freeBuffers=16 eventsLost=0 buffersWritten=310875 logBuffersLost=0 realTimeBuffersLost=0] forwarder[id=0 host=host1.internal port=514 state=connected bytesSent=5629 eventsSent=42 connects=1] eventQueue[eventsProcessed=42 eventsQueued=0 eventsDropped=0]

Full message - with log-syslog-header bsd set:

<30>Mar 24 10:00:00 windows2025 dnsstream[6824]: metrics: etwReader[numberOfBuffers=16 freeBuffers=16 eventsLost=0 buffersWritten=310875 logBuffersLost=0 realTimeBuffersLost=0] forwarder[id=0 host=host1.internal port=514 state=connected bytesSent=5629 eventsSent=42 connects=1] eventQueue[eventsProcessed=42 eventsQueued=0 eventsDropped=0]

Multi-target example

A deployment with two forwarding targets - one connected, one attempting to connect:

metrics: etwReader[numberOfBuffers=16 freeBuffers=16 eventsLost=0 buffersWritten=310875 logBuffersLost=0 realTimeBuffersLost=0] forwarder[id=0 host=host1.internal port=514 state=connected bytesSent=5629 eventsSent=42 connects=1] forwarder[id=1 host=host2.internal port=6514 state=not-connected bytesSent=0 eventsSent=0 connects=0] eventQueue[eventsProcessed=42 eventsQueued=0 eventsDropped=0]

Each forwarder block is structurally identical regardless of how many targets are configured. The id field is the discriminator. In the single-target case there is exactly one forwarder block; in multi-target deployments there is one block per configured target. Parsers should treat forwarder as a repeating block and match all instances.

Syslog parser pattern

For SIEM parsers and regex-based extraction, the repeating forwarder block can be captured with a repeating named group. In a key-value style extraction pipeline, match on metrics: as the event type identifier first, then extract the etwReader[...], eventQueue[...], and all forwarder[...] blocks separately.

Pseudocode pattern:

^metrics:\s+etwReader\[(?P<etw>[^\]]+)\]\s+(?P<clients>(?:forwarder\[[^\]]+\]\s*)+)eventQueue\[(?P<queue>[^\]]+)\]

Then iterate over all forwarder[...] matches within the clients capture group.

JSON metrics event

When log-metrics-to-eventlog on is configured, DnsStream emits a JSON metrics event using the same top-level envelope as other events. The forwarders field is an array - one object per configured forwarding target - which handles single and multi-target deployments with the same structure.

Single-target example

{
  "timestamp": "2000-01-01T19:00:00Z",
  "host":      "windows2025",
  "schema":    1,
  "type":      "metrics",
  "data": {
    "etwReader": {
      "numberOfBuffers":      16,
      "freeBuffers":          16,
      "eventsLost":           0,
      "buffersWritten":       310875,
      "logBuffersLost":       0,
      "realTimeBuffersLost":  0
    },
    "forwarders": [
      {
        "id":         0,
        "host":       "host1.internal",
        "port":       514,
        "state":      "connected",
        "bytesSent":  5629,
        "eventsSent": 42,
        "connects":   1
      }
    ],
    "eventQueue": {
      "eventsProcessed": 42,
      "eventsQueued":    0,
      "eventsDropped":   0
    }
  }
}

Multi-target example

{
  "timestamp": "2000-01-01T19:00:00Z",
  "host":      "windows2025",
  "schema":    1,
  "type":      "metrics",
  "data": {
    "etwReader": {
      "numberOfBuffers":      16,
      "freeBuffers":          16,
      "eventsLost":           0,
      "buffersWritten":       310875,
      "logBuffersLost":       0,
      "realTimeBuffersLost":  0
    },
    "forwarders": [
      {
        "id":         0,
        "host":       "host1.internal",
        "port":       514,
        "state":      "connected",
        "bytesSent":  5629,
        "eventsSent": 42,
        "connects":   1
      },
      {
        "id":         1,
        "host":       "host2.internal",
        "port":       6514,
        "state":      "not-connected",
        "bytesSent":  0,
        "eventsSent": 0,
        "connects":   0
      }
    ],
    "eventQueue": {
      "eventsProcessed": 42,
      "eventsQueued":    0,
      "eventsDropped":   0
    }
  }
}

Field reference

etwReader

The ETW reader section reports the state of the Windows ETW session through which DnsStream receives DNS events from the DNS Server service.

All counters in this section are reported as deltas for the current metrics interval, not cumulative totals.

Field Type Example Description
numberOfBuffers integer 16 Total number of ETW buffers allocated to the DnsStream trace session. Controlled by trace-maximum-buffers in dnsstream.conf.
freeBuffers integer 16 Number of ETW buffers not currently in use at the time of sampling. A value consistently equal to numberOfBuffers indicates the ETW session is draining buffers faster than they fill. A value of 0 indicates ETW buffer pressure.
eventsLost integer 0 Number of DNS events dropped by the ETW subsystem during this interval because all buffers were full when the event was generated. This is ETW-side loss, distinct from queue-side loss reported in eventQueue.eventsDropped. Any non-zero value means DNS events were lost before DnsStream could receive them.
buffersWritten integer 310875 Number of ETW buffers delivered to DnsStream during this interval. A consistently non-zero value confirms the ETW session is active and receiving events.
logBuffersLost integer 0 ETW buffers lost to disk-based logging during this interval. Should always be 0 - DnsStream uses real-time ETW delivery, not file-based logging. A non-zero value indicates an unexpected ETW session configuration issue.
realTimeBuffersLost integer 0 ETW buffers lost in real-time delivery to DnsStream during this interval. Distinct from eventsLost - this counts buffer-level loss rather than event-level loss. Non-zero values indicate the DnsStream consumer thread is not draining buffers fast enough.

forwarder

One block per configured forwarding target. In syslog format, each target appears as a separate forwarder[...] block identified by id. In JSON, all targets appear as objects in the forwarders array.

All counters in this section are reported as deltas for the current metrics interval.

Field Type Example Description
id integer 0 Zero-based index identifying this forwarding target. Corresponds to the order targets are listed in dnsstream.conf. Stable across metrics intervals for the lifetime of the service process.
host string "host1.internal" Hostname or IP address of the forwarding target as configured in forwarder.
port integer 514 TCP port of the forwarding target.
state string "connected" Current connection state. Either connected or not-connected.
bytesSent integer 5629 Number of bytes successfully written to this target’s TCP connection during this interval.
eventsSent integer 42 Number of events successfully forwarded to this target during this interval. This is the most operationally useful counter for throughput and health monitoring.
connects integer 1 Number of TCP connections established to this target during this interval. A value greater than 0 indicates at least one connection or reconnection occurred. Persistent non-zero values across intervals indicate connection instability.

eventQueue

The event queue section reports the state of the in-memory ring buffer that sits between ETW capture and network forwarding.

Counters represent activity during the current metrics interval.

Field Type Example Description
eventsProcessed integer 42 Number of events removed from the queue and handed to the forwarding thread during this interval. Under normal operation this tracks closely with ingestion rate.
eventsQueued integer 0 Number of events currently sitting in the ring buffer awaiting forwarding at the time of sampling. Under normal operation this should be zero or near zero. A persistently growing value indicates forwarding cannot keep pace with capture.
eventsDropped integer 0 Number of events discarded during this interval because the ring buffer was full when they arrived. This is queue-side loss, distinct from the ETW-side loss reported in etwReader.eventsLost. Any non-zero value means events were captured from ETW but could not be queued for forwarding and were permanently discarded.

eventsLost vs eventsDropped

These two fields measure loss at different points in the pipeline and are reported as interval-based values.

Field Location Cause Resolution
etwReader.eventsLost ETW subsystem DnsStream’s ETW consumer thread is not draining ETW buffers fast enough. Events are lost before DnsStream receives them. Check CPU usage. Review trace-buffer-size and trace-maximum-buffers settings.
eventQueue.eventsDropped Ring buffer The ring buffer is full because forwarding is interrupted or too slow to drain it. Events are received by DnsStream but cannot be queued. Increase queue-size. Investigate the forwarding connection.

Windows Event Log

When log-metrics-to-eventlog on is configured, DnsStream writes metrics to the Windows Event Log under the Telemity DnsStream provider. The raw metrics payload is written as the event message body, identical in structure to the syslog format but without the metrics: prefix regardless of whether log-format json is set:

etwReader[numberOfBuffers=16 freeBuffers=16 eventsLost=0 buffersWritten=310875 logBuffersLost=0 realTimeBuffersLost=0] forwarder[id=0 host=host1.internal port=514 state=connected bytesSent=5629 eventsSent=42 connects=1] eventQueue[eventsProcessed=42 eventsQueued=0 eventsDropped=0]

Interpreting metrics

Healthy steady state

A DnsStream instance operating normally shows:

  • etwReader.eventsLost = 0
  • etwReader.realTimeBuffersLost = 0
  • etwReader.freeBuffers > 0
  • etwReader.buffersWritten incrementing between intervals
  • All forwarder entries with state = connected
  • forwarder.eventsSent incrementing between intervals
  • eventQueue.eventsQueued near 0
  • eventQueue.eventsDropped = 0

Abnormal states

etwReader.buffersWritten is not incrementing

DnsStream is not receiving any ETW buffers. The ETW session may have detached, or the DNS Server service may have stopped generating events. Verify the DNS service is running and receiving queries.

etwReader.freeBuffers is 0

All ETW buffers are in use. The DnsStream consumer thread is not draining them fast enough. If sustained, eventsLost will begin to increment. Check CPU usage on the DNS server and review the trace-buffer-size and trace-maximum-buffers settings.

etwReader.eventsLost is non-zero

DNS events were dropped by the ETW subsystem before DnsStream could receive them. This is the most upstream form of loss - these events are gone entirely. See the resolution in the eventsLost vs eventsDropped table above.

etwReader.realTimeBuffersLost is non-zero

ETW buffers were dropped in real-time delivery. Similar cause to eventsLost but measured at the buffer level. Investigate DnsStream CPU usage and ETW buffer configuration.

forwarder.state is not connected

One or more forwarding targets are not currently connected. In Core, if the single target is not connected, no events are being forwarded and the queue is filling. In Assured, forwarding continues to the remaining connected targets. Check network connectivity and the Windows Event Log for connection error detail.

forwarder.connects is growing rapidly

The connection to a target is repeatedly dropping and reconnecting. Persistent instability - check network conditions between the DNS server and the collector, client TLS certificate availability and status if being used (Assured users only), and the collector’s own health.

eventQueue.eventsQueued is growing

The ring buffer is accumulating events faster than they are being forwarded. A forwarding bottleneck or outage is in progress. Check forwarder.state entries. If the queue fills completely, eventsDropped will begin to increment.

eventQueue.eventsDropped is non-zero

Events were received from ETW and queued, but had to be discarded because the ring buffer was full. Increase queue-size in dnsstream.conf and resolve the underlying forwarding issue. Any non-zero drop count means DNS telemetry events have been permanently lost.

This page