Operations¶
This page is the operator's reference for a running
pdns-pf-device-register instance: how to control the service, how to
watch it, which metrics to look at, and how to reach for the
pdns-pf-udp-linecat helper when you need to poke at it by hand.
Service control¶
The RPM ships a systemd unit named pdns-pf-device-register.service,
running as the pdns-device-register user. Everyday commands:
# Status and recent logs
systemctl status pdns-pf-device-register
# Follow the log stream
journalctl -u pdns-pf-device-register -f
# Restart after a config change
systemctl reload-or-restart pdns-pf-device-register
The service does not watch its config file for changes; restart it
after editing pdns-pf-device-register.yaml.
Config location¶
The shipped systemd unit points the service at
/etc/pdns-pf-device-register.yaml. Two heavily-commented
templates ship alongside it:
/etc/pdns-pf-device-register-consumer.example.yamlfor a NATS split-consumer instance./etc/pdns-pf-device-register-producer.example.yamlfor a NATS split-producer instance.
See Configuration for the full reference.
Command-line flags¶
When running the service in the foreground for troubleshooting — for
example under strace, or by hand out of the package's install path
— these are all the flags it accepts:
| Flag | Default | Purpose |
|---|---|---|
--config |
/etc/pdns-pf/device-register.yaml (binary default) |
Path to the YAML config file. The shipped systemd unit overrides this to /etc/pdns-pf-device-register.yaml, which is the path you should edit on a deployed box. |
--debug |
false |
Enable debug-level logging for this process. Overrides log.level. Verbose — use sparingly on a production instance. |
--nats-producer-rate-limit |
1000 |
Per-instance rate limit for a NATS producer, in messages per second. Ignored in combined and consumer modes. 0 disables the limit entirely; messages dropped by the limiter increment the deviceregister_nats_producer_rate_limited_total counter. |
Observability¶
The service exposes all of its live-inspection surfaces on the single
webserver bound to http.address:
- Status page. A minimal HTML summary served at
/. Shows which mode the process is running in (combined,producer, orconsumer) and links to the metrics endpoint. - Prometheus metrics. Scrape endpoint at
/metrics. See the Metrics reference below. - pprof. Go
net/http/pprofhandlers under/debug/pprof/for CPU, heap, goroutine and block profiles.
Logs go to standard error. Under the default systemd unit they are
captured by the journal under the pdns-pf-device-register syslog
identifier, so journalctl -u pdns-pf-device-register and
journalctl -t pdns-pf-device-register both work.
Metrics reference¶
All metrics are exposed at /metrics on the
http.address listener. Every metric
name is prefixed with deviceregister_ (included in the tables below
for grep-ability).
Build and UDP receiver¶
| Metric | Type | Meaning |
|---|---|---|
deviceregister_version |
gauge | Set to 1 with a version label carrying the running binary's version string. |
deviceregister_request_total |
counter | Total UDP datagrams received on the listener. |
deviceregister_request_queue_length |
gauge | Current depth of the UDP-to-processor channel. A persistently high value means the processor cannot keep up with the listener. |
Message processing¶
These cover the dedup / rate-limit stage. The blocklist semantics
they surface are explained in
Architecture → Blocklist. Note that the
two *_blacklisted_total metric names below are kept for historical
compatibility with existing dashboards — the docs and the config
otherwise use "blocklist".
| Metric | Type | Meaning |
|---|---|---|
deviceregister_request_valid_total |
counter | Messages parsed successfully into a (username, deviceid) pair. |
deviceregister_request_deviceid_invalid_total |
counter | Messages rejected because the device id failed validation. |
deviceregister_request_duplicate_total |
counter | Messages dropped by the deduplicator. |
deviceregister_request_accepted_total |
counter | Messages that passed dedup and rate limiting and entered the write pipeline. |
deviceregister_request_blacklisted_total |
counter | Messages dropped because the user was already on the blocklist. |
deviceregister_user_blacklisted_total |
counter | Number of times a user was newly added to the blocklist (i.e. blocklist transitions, not per-message drops). |
deviceregister_db_pipeline_dropped_total |
counter | Messages dropped because the database pipeline's input queue was full. |
deviceregister_kafka_blockeduser_pipeline_dropped_total |
counter | Messages for blocked users dropped because the Kafka pipeline's input queue was full. |
Database pipeline¶
| Metric | Type | Meaning |
|---|---|---|
deviceregister_database_updated_total |
counter | Devices successfully inserted or updated in Postgres. |
deviceregister_database_error_total |
counter | Failed Postgres operations, all errors combined. |
deviceregister_database_errors |
counter vec | Postgres errors broken down by error category (labelled counter). |
deviceregister_database_queue_length |
gauge | Depth of the database worker queue. |
deviceregister_database_redis_devices_dropped_total |
counter | Devices the database pipeline could not forward to the Redis pipeline because its input queue was full. |
Redis pipeline¶
| Metric | Type | Meaning |
|---|---|---|
deviceregister_redis_updated_total |
counter | Devices successfully written to Redis via the embedded Lua script. |
deviceregister_redis_error_total |
counter | Failed Redis operations, all errors combined. |
deviceregister_redis_errors |
counter vec | Redis errors broken down by error category. |
deviceregister_redis_queue_length |
gauge | Depth of the Redis worker queue. |
Kafka sender¶
These metrics are only meaningful when the kafka
section is configured.
| Metric | Type | Meaning |
|---|---|---|
deviceregister_kafka_sender_bytes_total |
counter | Bytes sent to Kafka. |
deviceregister_kafka_sender_messages_total |
counter | Messages sent to Kafka. |
deviceregister_kafka_sender_send_errors_total |
counter | Kafka write failures. |
deviceregister_kafka_sender_marshal_failed_total |
counter | Protobuf marshal failures before the message ever reached Kafka. Should stay at zero. |
deviceregister_kafka_sender_queue_length |
gauge | Depth of the Kafka sender's input queue. |
deviceregister_kafka_sender_devices_dropped_total |
counter | Devices dropped because the Kafka sender's input queue was full. |
deviceregister_kafka_redis_pipeline_dropped_total |
counter | Devices the Kafka sender could not forward to the Redis pipeline because its input queue was full. |
dstore_alert sender¶
Only meaningful when dstore.alert-address
is set.
| Metric | Type | Meaning |
|---|---|---|
deviceregister_dstore_alert_sender_bytes_total |
counter | Bytes sent to dstore_alert. |
deviceregister_dstore_alert_sender_messages_total |
counter | Messages sent to dstore_alert. |
deviceregister_dstore_alert_sender_send_errors_total |
counter | Failed sends to dstore_alert. |
deviceregister_dstore_alert_sender_marshal_failed_total |
counter | Protobuf marshal failures. Should stay at zero. |
deviceregister_dstore_alert_sender_queue_length |
gauge | Depth of the dstore_alert sender queue. |
deviceregister_dstore_alert_sender_connections_total |
counter | Successful TCP connections established to dstore_alert. A counter that only climbs during (re)connect, so a jumping value means the upstream is flapping. |
deviceregister_dstore_alert_sender_devices_dropped_total |
counter | Devices dropped because the dstore_alert sender's input queue was full. |
NATS producer¶
Only meaningful on a NATS split-producer instance.
| Metric | Type | Meaning |
|---|---|---|
deviceregister_nats_producer_sent_total |
counter | Devices successfully published to NATS. |
deviceregister_nats_producer_rate_limited_total |
counter | Devices dropped by the --nats-producer-rate-limit limiter. |
deviceregister_nats_producer_error_total |
counter | Failed NATS publishes. |
NATS consumer¶
Only meaningful on a NATS split-consumer instance.
| Metric | Type | Meaning |
|---|---|---|
deviceregister_nats_consumer_received_total |
counter | Devices received from NATS. |
deviceregister_nats_consumer_json_error_total |
counter | NATS messages that failed to decode as a device struct. Should stay at zero — non-zero means a producer is emitting a payload this consumer does not understand. |
Companion tool: pdns-pf-udp-linecat¶
The RPM also ships pdns-pf-udp-linecat, a small helper that reads
lines from standard input and sends each one as a single UDP datagram.
It is how you poke at a combined or split-producer instance by hand —
either to smoke-test a fresh deployment, feed a canned test corpus,
or demonstrate the blocklist logic.
| Flag | Default | Purpose |
|---|---|---|
-address |
127.0.0.1:4313 |
host:port of the target UDP listener. Point at your udp.address. |
-hex |
false |
Treat each input line as a hex-encoded binary payload. Useful for replaying non-ASCII packets captured from production. |
-rate |
0 |
Rate limit in packets per second. 0 is unlimited. |
-burst |
0 |
Burst size for the rate limiter. 0 lets the tool pick something reasonable based on -rate. |
Examples:
# Register a single device by hand
echo "NEWD some-test-user aabbcc112233" | pdns-pf-udp-linecat
# Replay a canned corpus of 100 users each registering one device
pdns-pf-udp-linecat < 100-users-1-device.txt
# Demonstrate the blocklist by replaying one user with 100 devices
pdns-pf-udp-linecat < single-user-100-devices.txt
The last example trips the default blocklist threshold (10 devices in
20 seconds): you should see
deviceregister_request_blacklisted_total and
deviceregister_user_blacklisted_total climb on the target instance.
On exit, the tool prints a messages-per-second figure, which makes it
an acceptable stand-in for a dedicated load generator when tuning
workers pool sizes or chasing a throughput regression.