Operations¶
Service control¶
The RPM ships a systemd template unit named
pdns-pf-oxfeed-httpapi-downloader@.service, running as the
pdns-oxfeed user. No instances are enabled by default — each
deployment picks the instances to run by linking the template:
# Create a config file
cp /etc/pdns-pf/oxfeed-httpapi-downloader/example.yml \
/etc/pdns-pf/oxfeed-httpapi-downloader/SOMENAME.yml
# Enable the instance
ln -s /lib/systemd/system/pdns-pf-oxfeed-httpapi-downloader@.service \
/etc/systemd/system/pdns-pf-oxfeed-httpapi-downloader@SOMENAME.service
systemctl daemon-reload
systemctl enable --now pdns-pf-oxfeed-httpapi-downloader@SOMENAME
The @SOMENAME suffix maps to the <INSTANCE> placeholder in the
config path. Everyday commands for a named instance:
systemctl status pdns-pf-oxfeed-httpapi-downloader@SOMENAME
journalctl -u pdns-pf-oxfeed-httpapi-downloader@SOMENAME -f
systemctl restart pdns-pf-oxfeed-httpapi-downloader@SOMENAME
The service does not watch its config file for changes; restart the instance after editing its YAML.
Config location¶
Each instance reads
/etc/pdns-pf/oxfeed-httpapi-downloader/<INSTANCE>.yml. The
commented template installed at
/etc/pdns-pf/oxfeed-httpapi-downloader/example.yml covers every
field. See Configuration for the full
reference.
Command-line flags¶
| Flag | Default | Purpose |
|---|---|---|
-config |
— | Path to the YAML config file. The shipped systemd unit always passes this. |
-expand-env |
off | Expand $VAR / ${VAR} references from the environment inside the YAML before parsing. Use this to inject the upstream password from a systemd drop-in. |
-strict |
off | Reject unknown YAML keys instead of ignoring them. Useful when validating a hand-written config. |
-o |
— | Override feed.root from the command line. Accepts a path or a simpleblob URI such as s3://bucket?region=.... |
-http-addr |
— | Override http.address from the command line (example: :9917). |
-http-serve-feed |
off | Override http.serve_feed from the command line. |
-debug |
off | Shortcut for log.level: debug. |
-log-level |
(config) | Override log.level. |
-log-format |
(config) | Override log.format. |
-log-timestamp |
(config) | Override log.timestamp. |
-cpuprofile |
— | Write a Go CPU profile to the given path on exit. |
-memprofile |
— | Write a Go heap profile to the given path on exit. |
-version |
— | Print the version and exit. |
When no -config is given, the binary defaults to a single fetch
cycle and then exits. With -config present, the default flips to
watch mode — set run_once: true in the YAML to keep one-shot
behaviour under systemd.
Observability¶
All live-inspection surfaces are served by the HTTP server bound to
http.address. The shipped vtfeed
profile listens on :4717; other deployments pick their own port.
- Status page.
/serves an HTML summary of the feed: current version, last update time, files present, expiry queue. - Health check.
/healthzreturns a JSON health summary from the embeddedgo-healthzlibrary. See Healthz checks. - Prometheus metrics. Scraped at
/metrics. See Metrics. - pprof. Go
net/http/pprofhandlers under/debug/pprof/for CPU, heap, goroutine, and block profiles. - Feed directory (optional). If
http.serve_feed: true, the feed directory is served at/feed/. For development only.
Log verbosity is controlled by log.level in the config or the
-debug / -log-level flags. At debug level the downloader logs
each upstream request, the URL fetched, response status, and feed
write progress.
Healthz checks¶
The shared commandsource package registers three named checks:
| Check | Threshold | Meaning |
|---|---|---|
feed_size |
warn when 0 entries | The internal feed is empty — usually means upstream returned no data yet, or the initial snapshot failed. |
feed_version |
error when 0 | No version has been written yet. |
feed_source_version |
error when empty | The downloader has not yet received a version from upstream. This is normal at startup; if it stays in this state, the upstream is unreachable. |
Metrics¶
All metrics are exposed at /metrics in Prometheus exposition format.
The downloader exports two families: shared feed-write counters from
the commandsource package, and HTTP-upstream counters from the
httpsource package.
Feed state¶
| Metric | Type | Meaning |
|---|---|---|
oxfeed_feed_current_version |
Gauge | Version number of the latest snapshot written to the feed directory. |
oxfeed_feed_current_version_entries |
Gauge | Number of domain entries in the latest snapshot. NaN until the first snapshot is written. |
oxfeed_feed_size_bytes |
Gauge | Approximate size of the current feed dataset in bytes. |
oxfeed_feed_prune_call_total |
Counter | Total memdb prune operations executed. |
oxfeed_feed_prune_saved_bytes_total |
Counter | Bytes recovered by memdb pruning since startup. |
Upstream HTTP traffic¶
The endpoint label has three values: codes, snapshot, incremental.
| Metric | Type | Labels | Meaning |
|---|---|---|---|
oxfeed_source_httpapi_request_total |
Counter | endpoint |
Outgoing requests, per endpoint. |
oxfeed_source_httpapi_request_status_total |
Counter | endpoint, status |
Distribution of HTTP status codes seen per endpoint. |
oxfeed_source_httpapi_request_error_total |
Counter | endpoint |
Requests that returned a non-2xx response. |
oxfeed_source_httpapi_request_duration_seconds |
Histogram | endpoint |
Request duration per endpoint, with buckets from 10 ms to 24 h. |
oxfeed_source_httpapi_feed_success_last_time_seconds |
Gauge | — | Unix timestamp of the last successful snapshot or delta fetch. |
oxfeed_source_httpapi_feed_change_total |
Counter | — | Times the upstream feed version changed in this session. |
oxfeed_source_httpapi_feed_change_last_time_seconds |
Gauge | — | Unix timestamp of the last feed-change event. |
oxfeed_source_httpapi_codes_success_last_time_seconds |
Gauge | — | Unix timestamp of the last successful codes fetch. |
oxfeed_source_httpapi_codes_change_total |
Counter | — | Times the upstream code map changed in this session. |
oxfeed_source_httpapi_codes_change_last_time_seconds |
Gauge | — | Unix timestamp of the last codes-change event. |
A steady stream of status=304 responses on incremental is the
normal idle case — it means the downloader is polling and the upstream
has no new data. Sustained status=410 on incremental indicates the
downloader's stored version is too old; the next iteration will fetch
a full snapshot. Persistent 5xx values warrant looking at the upstream
itself.
Profiling¶
-cpuprofile <path> starts a CPU profile at startup and writes it on
clean shutdown; -memprofile <path> writes a heap profile on clean
shutdown. Both are intended for short ad-hoc runs (-run_once: true
or sending SIGTERM after the issue reproduces); they are not
appropriate for long-running production processes because the CPU
profile keeps file handles open and the heap profile is only written
on exit.
The /debug/pprof/ HTTP handlers offer the same data without
restarting the process — prefer them for live diagnosis.