Operations¶
Service control¶
The RPM ships a systemd template unit named
pdns-pf-oxfeed-commandsource@.service, running as the
pdns-oxfeed user. One instance is started per logical feed.
To add an instance called my-feed:
# 1. Drop a config file for this instance.
cp /etc/pdns-pf/oxfeed-commandsource/example.yml \
/etc/pdns-pf/oxfeed-commandsource/my-feed.yml
$EDITOR /etc/pdns-pf/oxfeed-commandsource/my-feed.yml
# 2. Enable an instance of the template unit.
ln -s /lib/systemd/system/pdns-pf-oxfeed-commandsource@.service \
/etc/systemd/system/pdns-pf-oxfeed-commandsource@my-feed.service
# 3. Bring it up.
systemctl daemon-reload
systemctl enable --now pdns-pf-oxfeed-commandsource@my-feed
Everyday commands for an existing instance:
# Status and recent logs
systemctl status pdns-pf-oxfeed-commandsource@my-feed
# Follow the log stream
journalctl -u pdns-pf-oxfeed-commandsource@my-feed -f
# Restart after a config change
systemctl restart pdns-pf-oxfeed-commandsource@my-feed
The service does not watch its config file for changes; restart the instance after editing.
Config location¶
Each instance reads
/etc/pdns-pf/oxfeed-commandsource/<instance>.yml. The RPM ships
a commented template at
/etc/pdns-pf/oxfeed-commandsource/example.yml but does not
install a ready-to-use per-instance config. See
Configuration for the full reference.
Command-line flags¶
| Flag | Default | Purpose |
|---|---|---|
-config |
— | Path to the YAML config file. The packaged unit passes the per-instance file. |
-expand-env |
false |
Expand ${VAR} references inside the YAML file. |
-strict |
false |
Reject unknown YAML fields instead of ignoring them. |
-o |
— | Override feed.root with a filesystem path or simpleblob:// URI. |
-http-addr |
(config) | Override http.address. |
-http-serve-feed |
false |
Override http.serve_feed. |
-debug |
false |
Shortcut for -log-level=debug. |
-cpuprofile |
— | Write a CPU pprof to this file when the process exits. |
-memprofile |
— | Write a heap profile to this file when the process exits. |
-log-level |
(config) | Override log.level. |
-log-format |
(config) | Override log.format. |
-log-timestamp |
(config) | Override log.timestamp. |
The service needs a configured
feed.command_source.command
before it can start; there is no positional command argument or flag that
sets it. When that command is supplied by configuration, run_once
defaults to false for long-lived daemon operation and can be set to
true for a single update cycle.
HTTP endpoints¶
The HTTP server bound to http.address
exposes:
- Status page (
/). HTML summary of the running feed: feed UUID, whether snapshots are LMDB-sorted, whethernamespace_per_codeis active, current source version, total feed size, and per-snapshot / per-delta tables. - Metrics (
/metrics). Prometheus endpoint. See Metrics. - Healthz (
/healthz). JSON response from the embeddedgo-healthzlibrary. See Healthz checks below. - pprof (
/debug/pprof/...). Gonet/http/pprofhandlers for CPU, heap, goroutine, and block profiles. - Feed tree (
/feed/). Only whenhttp.serve_feedis set. Intended for development and testing only.
Healthz checks¶
The service registers three checks that share a single lifecycle: all three return OK until the first successful update lands, then switch to reflecting the real feed state.
| Check | Warn / errors when |
|---|---|
feed_size |
Warns when the published feed contains no data. |
feed_version |
Errors when no feed version exists (snapshots and deltas are both empty). |
feed_source_version |
Errors when the last accepted source version is empty. |
The "passive until first update" behaviour means a freshly started
instance does not page during warm-up, but a stuck instance — one
that never produces a first successful update — will not page either.
Pair healthz with the
oxfeed_source_command_exec_success_last_time_seconds
metric to alert on warm-up failures.
Writing a source command¶
The command contract is documented under
Architecture → The command contract.
A minimal /bin/sh skeleton looks like:
#!/bin/sh
set -eu
# OXFEED_TMPDIR is provided by the service and cleaned up on exit.
csv="$OXFEED_TMPDIR/feed.csv"
codes="$OXFEED_TMPDIR/feed-codes.json"
# Bail out early if nothing changed since the last accepted version.
if my-source --version-only | grep -qxF "${OXFEED_LAST_VERSION-}"; then
exit 11 # "not modified"
fi
# Produce deterministic output: no timestamps, fixed sort order.
my-source --emit-csv > "$csv"
my-source --emit-codes > "$codes"
# Hand the files off to the service. The version field is optional
# but lets the service feed it back in OXFEED_LAST_VERSION next time.
printf 'OXFEED_GENERATOR_RESULT: {"v":1,"csv_file":%s,"codes_file":%s,"version":%s}\n' \
"\"$csv\"" "\"$codes\"" "\"$(my-source --version-only)\""
The service reads csv_file and codes_file, hashes them, and only
emits a delta when the contents actually changed. Tools like the
admin's pdns-pf-admin-manage export_oxfeed subcommand follow this
contract.
Profiling¶
-cpuprofile <path> writes a CPU profile and -memprofile <path>
writes a heap profile when the process exits, including on the next
systemctl stop. Combine with -once for short, bounded profiling
runs.
Live profiling is available via the pprof endpoints under
/debug/pprof/ on the status server. For example: