Skip to content

Operations

This page is the operator's reference for a running pdns-carbonizer instance: how to control the service, how to watch it, what HTTP and TCP surfaces it exposes, and how the two companion tools fit in.

Service control

The RPM ships a systemd unit named pdns-carbonizer.service, running as the pdns-carbonizer user. Everyday commands:

# Status and recent logs
systemctl status pdns-carbonizer

# Follow the log stream
journalctl -u pdns-carbonizer -f

# Restart after a config change
systemctl reload-or-restart pdns-carbonizer

The service does not watch its config file for changes; restart it after editing carbonizer.yml.

Config location

The default config path is /etc/pdns-carbonizer/carbonizer.yml. A commented template with every option is shipped alongside it as /etc/pdns-carbonizer/carbonizer.example.yml. See Configuration for the full reference.

Command-line flags

Flag Default Purpose
--config /etc/pdns-carbonizer/carbonizer.yml Path to the YAML config.
--http_address (from config) Override carbonizer.http_address without editing the config.
--listen_address (from config) Override carbonizer.listen_address.
--debug_address (from config) Override carbonizer.debug_address.
-version off Print the version string and exit.

HTTP endpoints

When carbonizer.http_address is set, the service exposes:

Path Content
/ HTML status page: Carbon destinations (with last-success time and error) and scrape targets (with last-scrape time, sample count, and shortcuts to the per-target views).
/metrics Prometheus metrics about the Carbonizer itself. See Metrics.
/last/scrape/<job>/<instance> Raw /metrics body of the latest successful scrape for one target. Plain text.
/last/carbon/<job>/<instance> Carbon lines produced from the latest scrape of one target. Plain text.
/tap Live stream of every successful scrape in the recording-frame format. Accepts an optional ?duration=30s to auto-close the stream.

The /last/... paths are useful when validating a template change: edit the config, restart the service, then visit /last/carbon/<job>/<instance> to see what gets emitted for one target without having to attach a TCP debugger.

TCP debug surfaces

Two raw TCP surfaces complement the HTTP endpoints. Both are disabled by default and enabled by setting the corresponding bind address:

  • debug_address dumps both the raw /metrics body and the converted Carbon for every successful scrape. The format includes per-target separators. Extremely verbose — use sparingly.
  • listen_address dumps only the Carbon lines. Connecting a shell to it (e.g. with nc) is the quickest way to confirm that a template change produces the paths you expect, without standing up a real Graphite server.
# Watch all converted Carbon lines as they would be sent on the wire.
nc 127.0.0.1 4849

Both surfaces use the same internal hub as the real Carbon clients, so attaching to them does not affect the live Carbon traffic.

Observability

  • Status page at / summarises destination and scrape health.
  • Prometheus metrics at /metrics. See Metrics for the full reference and PromQL snippets.
  • Per-target spot checks via /last/scrape/... and /last/carbon/....

Set log_scrape_errors to log one line per failing scrape; pair it with log_scrape_success only when diagnosing — it logs every successful scrape and gets very chatty.

Companion tools

The pdns-carbonizer-record RPM subpackage installs two extra binaries that operate on the same recording format the Carbonizer itself writes when carbonizer.record.dest_dir is set.

pdns-carbonizer-record

Reuses the Carbonizer config to scrape targets but writes the raw scrapes to one recording file (or stdout) instead of forwarding them as Carbon. None of the Carbon output, debug, or HTTP surfaces are started.

pdns-carbonizer-record [flags]
Flag Default Purpose
--config /etc/pdns-carbonizer/carbonizer.yml Config file. Only scrape_configs and the scrape timings are used.
-o stdout Output file path. - is also stdout.
-d unlimited How long to record, e.g. 5m. Records forever by default.
--interval (from config) Force a scrape interval for all jobs. Useful when capturing a denser window than the live config would.
-v off Verbose: log every scrape (errors and successes).
-version off Print the version string and exit.
# Record 10 minutes from the same targets the live Carbonizer scrapes,
# at a one-second interval, to a single file.
pdns-carbonizer-record \
    --config /etc/pdns-carbonizer/carbonizer.yml \
    -d 10m --interval 1s -o /tmp/snapshot.rec

The output uses the same on-disk frame format as the dir recorder (#[REC] header line, raw scrape body, blank line) but is not compressed. Pipe through bzip2 or gzip yourself if you want compression.

pdns-carbonizer-load

Replays a recording either into a PostgreSQL-backed Prometheus storage adapter, or as a stream of Prometheus text metrics with rewritten job / instance labels and the original scrape timestamps.

pdns-carbonizer-load [flags] < recording.rec
Flag Default Purpose
--postgres PostgreSQL connection string, e.g. user=postgres dbname=postgres port=5432 host=127.0.0.1 sslmode=disable. Required unless --convert is set.
--convert off Skip PostgreSQL; print rewritten Prometheus text metrics to stdout instead.
--honor-labels off Keep existing job / instance labels on metrics instead of renaming them to exported_job / exported_instance. Mirrors the Prometheus honor_labels semantics.
--prefix "" String to prefix to every job and instance value, separated by /. Useful when loading multiple recordings into the same database.
-v off Verbose.
-version off Print the version string and exit.

The PostgreSQL backend expects the timescale prometheus-postgresql-adapter schema. The whole recording is stored in one transaction — either the entire load succeeds or none of it is committed.

# Convert a recording to plain Prometheus text for offline inspection.
pdns-carbonizer-load --convert < /tmp/snapshot.rec > /tmp/snapshot.prom

# Load into the timescale adapter, prefixing every job/instance with "lab".
pdns-carbonizer-load \
    --postgres "user=postgres dbname=postgres host=127.0.0.1 sslmode=disable" \
    --prefix lab \
    < /tmp/snapshot.rec

Troubleshooting

  • ERROR: No scrape targets defined, exiting. Either scrape_configs is empty, or none of the entries have any static_configs.targets. The Carbonizer requires at least one target to start.
  • WARNING: No carbonizer.destinations configured, no carbon will be sent. Logged at startup when carbonizer.destinations is empty. The service still scrapes and exposes its own metrics, but produces no Carbon output. Intentional in some debugging setups; otherwise fill in destinations.
  • Samples are being dropped, but scrapes succeed. Watch carbonizer_carbon_convert_metric_error_total. Almost always the template references a label that the affected metrics do not have.
  • Carbon destination shows "never" on the status page. The Carbonizer has not been able to deliver a batch yet. Connect errors are logged at most once every 30 seconds per destination; also check carbonizer_carbon_send_connect_error_total.
  • No data in a freshly opened recording file. Dir recordings are bzip2-compressed with a large buffer. Several minutes at low scrape volume is normal before bytes appear; the buffer flushes when the file rolls over.