---
title: Power DNS Recursor
description: Keep an eye on strange traffic to and from your PowerDNS recursors.
breadcrumbs: Docs > Integrations > Power DNS Recursor
---

# Power DNS Recursor
Supported OS Integration version5.4.0
## Overview{% #overview %}

Track the performance of your PowerDNS Recursor and monitor strange or worrisome traffic. This Agent check collects a variety of metrics from your recursors, including those for:

- Query answer times-see how many responses take less than 1ms, 10ms, 100ms, 1s, or greater than 1s.
- Query timeouts.
- Cache hits and misses.
- Answer rates by type: SRVFAIL, NXDOMAIN, NOERROR.
- Ignored and dropped packets.

And many more.

**Minimum Agent version:** 6.0.0

## Setup{% #setup %}

### Installation{% #installation %}

The PowerDNS Recursor check is included in the [Datadog Agent](https://app.datadoghq.com/account/settings/agent/latest) package, so you don't need to install anything else on your recursors.

### Configuration{% #configuration %}

#### Prepare PowerDNS{% #prepare-powerdns %}

This check collects performance statistics using PowerDNS Recursor's statistics API. Versions of pdns_recursor before 4.1 do not enable the stats API by default. If you're running an older version, enable it by adding the following to your recursor config file, for example `/etc/powerdns/recursor.conf`:

```
webserver=yes
api-key=changeme             # only available since v4.0
webserver-readonly=yes       # default no
#webserver-port=8081         # default 8082
#webserver-address=0.0.0.0   # default 127.0.0.1
```

If you're running pdns_recursor 3.x, prepend `experimental-` to these option names, for example: `experimental-webserver=yes`.

If you're running pdns_recursor >= 4.1, just set `api-key`.

Restart the recursor to enable the statistics API.

{% tab title="Host" %}
#### Host{% #host %}

To configure this check for an Agent running on a host:

1. Edit the `powerdns_recursor.d/conf.yaml` file, in the `conf.d/` folder at the root of your [Agent's configuration directory](https://docs.datadoghq.com/agent/guide/agent-configuration-files.md#agent-configuration-directory). See the [sample powerdns_recursor.d/conf.yaml](https://github.com/DataDog/integrations-core/blob/master/powerdns_recursor/datadog_checks/powerdns_recursor/data/conf.yaml.example) for all available configuration options:

   ```yaml
   init_config:
   
   instances:
     ## @param host - string - required
     ## Host running the recursor.
     #
     - host: 127.0.0.1
   
       ## @param port - integer - required
       ## Recursor web server port.
       #
       port: 8082
   
       ## @param api_key - string - required
       ## Recursor web server api key.
       #
       api_key: "<POWERDNS_API_KEY>"
   
       ## @param version - integer - required - default: 3
       ## Version 3 or 4 of PowerDNS Recursor to connect to.
       ## The PowerDNS Recursor in v4 has a production ready web server that allows for
       ## statistics gathering. In version 3.x the server was marked as experimental.
       ##
       ## As the server was marked as experimental in version 3 many of the metrics have
       ## changed names and the API structure (paths) have also changed. With these changes
       ## there has been a need to separate the two concerns. The check now has a key value
       ## version: which if set to version 4 queries with the correct API path on the
       ## non-experimental web server.
       ##
       ## https://doc.powerdns.com/md/httpapi/api_spec/#url-apiv1serversserver95idstatistics
       #
       version: 3
   ```

1. [Restart the Agent](https://docs.datadoghq.com/agent/guide/agent-commands.md#start-stop-and-restart-the-agent).

##### Log collection{% #log-collection %}

1. Collecting logs is disabled by default in the Datadog Agent, you need to enable it in `datadog.yaml`:

   ```yaml
   logs_enabled: true
   ```

1. Add the `dd-agent` user to the `systemd-journal` group by running:

   ```text
   usermod -a -G systemd-journal dd-agent
   ```

1. Add this configuration block to your `powerdns_recursor.d/conf.yaml` file to start collecting your PowerDNS Recursor Logs:

   ```yaml
   logs:
     - type: journald
       source: powerdns
   ```

See the [sample powerdns_recursor.d/conf.yaml](https://github.com/DataDog/integrations-core/blob/master/powerdns_recursor/datadog_checks/powerdns_recursor/data/conf.yaml.example) for all available configuration options.

1. [Restart the Agent](https://docs.datadoghq.com/agent/guide/agent-commands.md#start-stop-and-restart-the-agent).

{% /tab %}

{% tab title="Containerized" %}
#### Containerized{% #containerized %}

For containerized environments, see the [Autodiscovery Integration Templates](https://docs.datadoghq.com/agent/kubernetes/integrations.md) for guidance on applying the parameters below.

| Parameter            | Value                                                                            |
| -------------------- | -------------------------------------------------------------------------------- |
| `<INTEGRATION_NAME>` | `powerdns_recursor`                                                              |
| `<INIT_CONFIG>`      | blank or `{}`                                                                    |
| `<INSTANCE_CONFIG>`  | `{"host":"%%host%%", "port":8082, "api_key":"<POWERDNS_API_KEY>", "version": 3}` |

##### Log collection{% #log-collection %}

Collecting logs is disabled by default in the Datadog Agent. To enable it, see [Kubernetes Log Collection](https://docs.datadoghq.com/agent/kubernetes/log.md).

| Parameter      | Value                    |
| -------------- | ------------------------ |
| `<LOG_CONFIG>` | `{"source": "powerdns"}` |

{% /tab %}

### Validation{% #validation %}

[Run the Agent's `status` subcommand](https://docs.datadoghq.com/agent/guide/agent-commands.md#agent-status-and-information) and look for `powerdns_recursor` under the Checks section.

## Data Collected{% #data-collected %}

### Metrics{% #metrics %}

|  |
|  |
| **powerdns.recursor.all\_outqueries**(gauge)               | The number of outgoing udp queries per second*Shown as query*                                                                                                          |
| **powerdns.recursor.answers0\_1**(gauge)                   | Number of queries per second answered within 1 millisecond*Shown as query*                                                                                             |
| **powerdns.recursor.answers100\_1000**(gauge)              | Number of queries per second answered within 1 second*Shown as query*                                                                                                  |
| **powerdns.recursor.answers10\_100**(gauge)                | Number of queries per second answered within 100 milliseconds*Shown as query*                                                                                          |
| **powerdns.recursor.answers1\_10**(gauge)                  | Number of queries per second answered within 10 milliseconds*Shown as query*                                                                                           |
| **powerdns.recursor.answers\_slow**(gauge)                 | Number of queries per second NOT answered within 1 second*Shown as query*                                                                                              |
| **powerdns.recursor.auth4\_answers0\_1**(gauge)            | Number of queries per second answered by auth4s within 1 millisecond; Available since pdns_recursor v4.x*Shown as query*                                               |
| **powerdns.recursor.auth4\_answers100\_1000**(gauge)       | Number of queries per second answered by auth4s within 1 second; Available since pdns_recursor v4.x*Shown as query*                                                    |
| **powerdns.recursor.auth4\_answers10\_100**(gauge)         | Number of queries per second answered by auth4s within 100 milliseconds; Available since pdns_recursor v4.x*Shown as query*                                            |
| **powerdns.recursor.auth4\_answers1\_10**(gauge)           | Number of queries per second answered by auth4s within 10 milliseconds; Available since pdns_recursor v4.x*Shown as query*                                             |
| **powerdns.recursor.auth4\_answers\_slow**(gauge)          | Number of queries per second NOT answered by auth4s within 1 second; Available since pdns_recursor v4.x*Shown as query*                                                |
| **powerdns.recursor.auth6\_answers0\_1**(gauge)            | Number of queries per second answered by auth6s within 1 millisecond; Available since pdns_recursor v4.x*Shown as query*                                               |
| **powerdns.recursor.auth6\_answers100\_1000**(gauge)       | Number of queries per second answered by auth6s within 1 second; Available since pdns_recursor v4.x*Shown as query*                                                    |
| **powerdns.recursor.auth6\_answers10\_100**(gauge)         | Number of queries per second answered by auth6s within 100 milliseconds; Available since pdns_recursor v4.x*Shown as query*                                            |
| **powerdns.recursor.auth6\_answers1\_10**(gauge)           | Number of queries per second answered by auth6s within 10 milliseconds; Available since pdns_recursor v4.x*Shown as query*                                             |
| **powerdns.recursor.auth6\_answers\_slow**(gauge)          | Number of queries per second NOT answered by auth6s within 1 second; Available since pdns_recursor v4.x*Shown as query*                                                |
| **powerdns.recursor.cache\_entries**(gauge)                | The number of entries in the cache*Shown as entry*                                                                                                                     |
| **powerdns.recursor.cache\_hits**(gauge)                   | The number of cache hits per second*Shown as hit*                                                                                                                      |
| **powerdns.recursor.cache\_misses**(gauge)                 | The number of cache misses per second*Shown as miss*                                                                                                                   |
| **powerdns.recursor.case\_mismatches**(gauge)              | The number of mismatches in character case per second*Shown as error*                                                                                                  |
| **powerdns.recursor.chain\_resends**(gauge)                | The number of queries per second chained to existing outstanding query*Shown as query*                                                                                 |
| **powerdns.recursor.client\_parse\_errors**(gauge)         | The number of unparsable packets per second*Shown as error*                                                                                                            |
| **powerdns.recursor.concurrent\_queries**(gauge)           | The number of MThreads currently running*Shown as query*                                                                                                               |
| **powerdns.recursor.dlg\_only\_drops**(gauge)              | The number of records dropped per second because of 'delegation only' setting; Available since pdns_recursor v4.x*Shown as record*                                     |
| **powerdns.recursor.dnssec\_queries**(gauge)               | The number of queries received per second with the DO bit set; Available since pdns_recursor v4.x*Shown as record*                                                     |
| **powerdns.recursor.dnssec\_result\_bogus**(gauge)         | The number of DNSSEC validations per second that had the Bogus state; Available since pdns_recursor v4.x                                                               |
| **powerdns.recursor.dnssec\_result\_indeterminate**(gauge) | The number of DNSSEC validations per second that had the Indeterminate state; Available since pdns_recursor v4.x                                                       |
| **powerdns.recursor.dnssec\_result\_insecure**(gauge)      | The number of DNSSEC validations per second that had the Insecure state; Available since pdns_recursor v4.x                                                            |
| **powerdns.recursor.dnssec\_result\_nta**(gauge)           | The number of DNSSEC validations per second that had the NTA (negative trust anchor) state; Available since pdns_recursor v4.x                                         |
| **powerdns.recursor.dnssec\_result\_secure**(gauge)        | The number of DNSSEC validations per second that had the Secure state; Available since pdns_recursor v4.x                                                              |
| **powerdns.recursor.dnssec\_validations**(gauge)           | The number of DNSSEC validations performed per second; Available since pdns_recursor v4.x                                                                              |
| **powerdns.recursor.dont\_outqueries**(gauge)              | The number of outgoing queries dropped per second because of 'dont query' setting*Shown as query*                                                                      |
| **powerdns.recursor.edns\_ping\_matches**(gauge)           | The number of servers per second that sent a valid EDNS PING response; Available since pdns_recursor v4.x*Shown as host*                                               |
| **powerdns.recursor.edns\_ping\_mismatches**(gauge)        | The number of servers per second that sent an invalid EDNS PING response; Available since pdns_recursor v4.x*Shown as host*                                            |
| **powerdns.recursor.failed\_host\_entries**(gauge)         | The number of servers that failed to resolve*Shown as host*                                                                                                            |
| **powerdns.recursor.ignored\_packets**(gauge)              | The number of non-query packets received per second on server sockets that should only get queries; Available since pdns_recursor v4.x*Shown as packet*                |
| **powerdns.recursor.ipv6\_outqueries**(gauge)              | The number of outgoing queries per second over IPv6                                                                                                                    |
| **powerdns.recursor.ipv6\_questions**(gauge)               | The number of end-user-initiated IPv6 UDP queries with the RD bit set*Shown as query*                                                                                  |
| **powerdns.recursor.max\_mthread\_stack**(gauge)           | The maximum amount of thread stack ever used                                                                                                                           |
| **powerdns.recursor.negcache\_entries**(gauge)             | The number of entries in the negative answer cache*Shown as entry*                                                                                                     |
| **powerdns.recursor.no\_error\_packets**(gauge)            | The number of erroneous packets received per second; Available since pdns_recursor v4.x*Shown as packet*                                                               |
| **powerdns.recursor.noedns\_outqueries**(gauge)            | The number of queries per second sent without EDNS; Available since pdns_recursor v4.x*Shown as query*                                                                 |
| **powerdns.recursor.noerror\_answers**(gauge)              | The number of NOERROR answers per second*Shown as operation*                                                                                                           |
| **powerdns.recursor.noping\_outqueries**(gauge)            | The number of queries per second sent without EDNS PING; Available since pdns_recursor v4.x*Shown as query*                                                            |
| **powerdns.recursor.nsset\_invalidations**(gauge)          | The number of times per second an nsset was dropped because it no longer worked; Available since pdns_recursor v4.x                                                    |
| **powerdns.recursor.nsspeeds\_entries**(gauge)             | The number of entries in the NS speeds map; Available since pdns_recursor v4.x*Shown as entry*                                                                         |
| **powerdns.recursor.nxdomain\_answers**(gauge)             | The number of NXDOMAIN answers per second*Shown as response*                                                                                                           |
| **powerdns.recursor.outgoing4\_timeouts**(gauge)           | The number of timeouts per second for outgoing UDP IPv4 queries; Available since pdns_recursor v4.x*Shown as timeout*                                                  |
| **powerdns.recursor.outgoing6\_timeouts**(gauge)           | The number of timeouts per second for outgoing UDP IPv6 queries; Available since pdns_recursor v4.x*Shown as timeout*                                                  |
| **powerdns.recursor.outgoing\_timeouts**(gauge)            | The number of outgoing UDP query timeouts per second*Shown as timeout*                                                                                                 |
| **powerdns.recursor.over\_capacity\_drops**(gauge)         | The number of questions per second dropped due to having reached concurrent query limit*Shown as query*                                                                |
| **powerdns.recursor.packetcache\_entries**(gauge)          | The number of entries in the packet cache*Shown as entry*                                                                                                              |
| **powerdns.recursor.packetcache\_hits**(gauge)             | The number of packet cache hits per second*Shown as hit*                                                                                                               |
| **powerdns.recursor.packetcache\_misses**(gauge)           | The number of packet cache misses per second*Shown as miss*                                                                                                            |
| **powerdns.recursor.policy\_drops**(gauge)                 | The number of packets dropped per second because of Lua policy decision*Shown as packet*                                                                               |
| **powerdns.recursor.policy\_result\_custom**(gauge)        | The number of packets per second that were sent a custom answer by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                          |
| **powerdns.recursor.policy\_result\_drop**(gauge)          | The number of packets per second dropped by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                                                 |
| **powerdns.recursor.policy\_result\_noaction**(gauge)      | The number of packets per second that were not actioned upon by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                             |
| **powerdns.recursor.policy\_result\_nodata**(gauge)        | The number of packets per second that were replied to with NODATA by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                        |
| **powerdns.recursor.policy\_result\_nxdomain**(gauge)      | The number of packets per second that were replied to with NXDOMAIN by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                      |
| **powerdns.recursor.policy\_result\_truncate**(gauge)      | The number of packets per second that were forced to TCP by the RPZ/filter engine; Available since pdns_recursor v4.x*Shown as packet*                                 |
| **powerdns.recursor.qa\_latency**(gauge)                   | The average latency in microseconds exponentially weighted over past 'latency-statistic-size' packets*Shown as microsecond*                                            |
| **powerdns.recursor.questions**(gauge)                     | The number of user initiated udp queries per second*Shown as operation*                                                                                                |
| **powerdns.recursor.real\_memory\_usage**(gauge)           | The amount of memory consumed by PowerDNS in bytes; Available since pdns_recursor v4.x*Shown as byte*                                                                  |
| **powerdns.recursor.resource\_limits**(gauge)              | The number of queries per second that could not be performed due to resource limits; Available since pdns_recursor v4.x*Shown as query*                                |
| **powerdns.recursor.server\_parse\_errors**(gauge)         | The number of server replied packets per second that could not be parsed*Shown as error*                                                                               |
| **powerdns.recursor.servfail\_answers**(gauge)             | The number of SERVFAIL answers per second*Shown as response*                                                                                                           |
| **powerdns.recursor.spoof\_prevents**(gauge)               | The number of times per second PowerDNS considers itself spoofed and drops data                                                                                        |
| **powerdns.recursor.sys\_msec**(gauge)                     | The number of CPU milliseconds spent in 'system' mode*Shown as millisecond*                                                                                            |
| **powerdns.recursor.tcp\_client\_overflow**(gauge)         | The number of outgoing queries dropped per second because of 'dont query' setting*Shown as query*                                                                      |
| **powerdns.recursor.tcp\_clients**(gauge)                  | The number of active TCP/IP clients per second                                                                                                                         |
| **powerdns.recursor.tcp\_outqueries**(gauge)               | The number of outgoing TCP queries per second*Shown as operation*                                                                                                      |
| **powerdns.recursor.tcp\_questions**(gauge)                | The number of incoming tcp queries per second*Shown as operation*                                                                                                      |
| **powerdns.recursor.throttle\_entries**(gauge)             | The number of entries in the throttle map*Shown as entry*                                                                                                              |
| **powerdns.recursor.throttled\_out**(gauge)                | The number of throttled outgoing UDP queries per second*Shown as operation*                                                                                            |
| **powerdns.recursor.too\_old\_drops**(gauge)               | The number of questions per second that were dropped because they were too old; Available since pdns_recursor v4.x*Shown as query*                                     |
| **powerdns.recursor.udp\_in\_errors**(gauge)               | The number of packets per second that were received faster than the OS could process them; Available since pdns_recursor v4.x*Shown as packet*                         |
| **powerdns.recursor.udp\_noport\_errors**(gauge)           | The number of UDP packets per second where an ICMP response was received saying the remote port was not listening; Available since pdns_recursor v4.x*Shown as packet* |
| **powerdns.recursor.udp\_recvbuf\_errors**(gauge)          | The number of errors per second caused in the UDP receive buffer; Available since pdns_recursor v4.x*Shown as error*                                                   |
| **powerdns.recursor.udp\_sndbuf\_errors**(gauge)           | The number of errors per second caused in the UDP send buffer; Available since pdns_recursor v4.x*Shown as error*                                                      |
| **powerdns.recursor.unauthorized\_tcp**(gauge)             | The number of TCP questions denied per second because of allow-from restrictions*Shown as operation*                                                                   |
| **powerdns.recursor.unauthorized\_udp**(gauge)             | The number of UDP questions denied per second because of allow-from restrictions*Shown as operation*                                                                   |
| **powerdns.recursor.unexpected\_packets**(gauge)           | The number of unexpected answers per second from remote servers*Shown as operation*                                                                                    |
| **powerdns.recursor.unreachables**(gauge)                  | The number times per second nameservers were unreachable                                                                                                               |
| **powerdns.recursor.uptime**(gauge)                        | The number of seconds PowerDNS has been running*Shown as second*                                                                                                       |
| **powerdns.recursor.user\_msec**(gauge)                    | The number of CPU milliseconds spent in 'user' mode*Shown as millisecond*                                                                                              |

### Events{% #events %}

The PowerDNS Recursor check does not include any events.

### Service Checks{% #service-checks %}

**powerdns.recursor.can\_connect**

Returns `CRITICAL` if the Agent check is unable to connect to the monitored Gearman instance. Returns `OK` otherwise.

*Statuses: ok, critical*

## Troubleshooting{% #troubleshooting %}

Need help? Contact [Datadog support](https://docs.datadoghq.com/help/).
