Operations¶
This page is the operator's reference for a running
pdns-pf-simulator-server instance: how to control the service, how to
watch it, which metrics to look at, and how to drive the REST API by
hand when you need a verdict for one specific domain.
Service control¶
The RPM ships a systemd unit named pdns-pf-simulator-server.service,
running as the pdns-simulator user. Everyday commands:
# Status and recent logs
systemctl status pdns-pf-simulator-server
# Follow the log stream
journalctl -u pdns-pf-simulator-server -f
# Restart after a config change
systemctl reload-or-restart pdns-pf-simulator-server
The service does not watch its config file for changes; restart it
after editing /etc/pdns-pf/simulator-server.yaml. The same is true
of the Lua entry-point file — workers load it once at startup, so any
change to the filter engine needs a restart to take effect.
Config location¶
The shipped systemd unit points the service at
/etc/pdns-pf/simulator-server.yaml. A heavily-commented template
ships alongside it at
/etc/pdns-pf/simulator-server.example.yaml.
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, -c |
/etc/pdns-pf/simulator.yaml (binary default) |
Path to the YAML config file. The shipped systemd unit overrides this to /etc/pdns-pf/simulator-server.yaml, which is the path you should edit on a deployed box. |
--debug |
false |
Force debug-level logging for this process. Overrides log.level. Verbose — use sparingly. |
--test-and-exit |
false |
Fire one synthetic lookup_domain request for www.example.com and exit. Used by the package's smoke test. Exits non-zero if the request fails. |
--version |
false |
Print the version string and exit. |
Observability¶
The service exposes all of its live-inspection surfaces on the single
webserver bound to http.address:
- Status page. A small HTML page served at
/. It echoes the lastinfopayload returned by the Lua side and links to the metrics endpoint and the REST API. - 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. - REST API. The four endpoints listed in REST API surface.
Logs go to standard error. Under the default systemd unit they are
captured by the journal under the pdns-pf-simulator-server syslog
identifier, so journalctl -u pdns-pf-simulator-server and
journalctl -t pdns-pf-simulator-server both work.
REST API surface¶
All four endpoints return application/json. Three of them are subject
to the api_keys check;
/api/v1/info is not.
GET /api/v1/domain¶
Domain categorization lookup. Returns the OX Feed classification codes that apply to the given domain, without applying any subscriber context.
Query parameters:
| Parameter | Required | Description |
|---|---|---|
domain |
yes | Domain name. IDNA-encoded by the server before lookup. |
path |
no | Optional path under the domain, used by feeds that classify by URL. |
curl -s -H "X-API-Key: $KEY" \
'https://simulator.internal:8671/api/v1/domain?domain=www.example.com'
GET|POST /api/v1/simulate¶
Full user simulation. Resolves the subscriber, applies their settings,
and runs the filter pipeline end to end. Parameters can be sent as
query string (GET) or application/x-www-form-urlencoded body
(POST). At least one of ip, username, or deviceid is needed
for the engine to resolve a subscriber.
This is also the endpoint used by proxy implementations that delegate
live decisions to the simulator. In the current OpenResty proxy this
happens when proxyremotebaseurl points at the simulator. In that
mode proxy-side errors from this endpoint become proxy failures: HTTP
requests return a backend error response, and TLS/SNI stream requests
are closed.
| Parameter | Description |
|---|---|
domain |
Domain name to check. IDNA-encoded by the server. Required. |
path |
Optional path under the domain. |
ip |
Client IP address. Used to look up the subscriber session. |
username |
Subscriber username. |
deviceid |
Hex-encoded device id. |
profile |
Numeric device profile to use instead of the one derived from the subscriber. |
settings |
JSON-encoded settings to override the subscriber's stored settings. Useful for "what would this user see if I changed setting X?" tests. |
rules_ip |
IP to use for rules that key on a netblock. Only affects netblock-based list rules. |
verbose |
Set to 1 to include detailed rule-evaluation logs in the response. |
vhost |
Optional virtual host identifier passed through to the filter engine. |
curl -s -H "X-API-Key: $KEY" \
'https://simulator.internal:8671/api/v1/simulate?domain=www.example.com&ip=192.0.2.1&verbose=1'
GET /api/v1/codemappings¶
Dump of the OX Feed classification code → name table from the local
LMDB. Returns 204 No Content when the OX Feed backend is not in use
or its mappings are not yet loaded.
GET /api/v1/info¶
Returns the most recent info payload from the Lua side. Refreshed
every maintenance tick (once per second). Useful as a liveness probe
and to confirm which region the instance reports for.
Metrics reference¶
All metrics are exposed at /metrics on the
http.address listener. The five simulator
metrics share a pdns_pf_simulator_ prefix; the version metric uses
the platform-wide pdns_platform_ prefix.
| Metric | Type | Meaning |
|---|---|---|
pdns_platform_version_info |
gauge | Set to 1 with a version label carrying the running binary's version string. Useful for build provenance in dashboards. |
pdns_pf_simulator_lua_workers |
gauge | Number of Lua workers configured. Reflects lua.workers at startup and does not change at runtime. |
pdns_pf_simulator_lua_worker_create_error_total |
counter vec | Failures creating a Lua worker, labelled by the error message. Should always be zero — non-zero means a worker failed to load the Lua entry point, and the service exits. |
pdns_pf_simulator_lua_call_total |
counter vec | Lua calls made by the worker, labelled by call (lookup_domain, simulate_user, codemappings, maintenance, info). |
pdns_pf_simulator_lua_call_error_total |
counter vec | Lua calls that returned an error, labelled by call. The ratio against pdns_pf_simulator_lua_call_total is the error rate per request type. |
pdns_pf_simulator_info |
gauge vec | Set to 1 with a region label sourced from the Lua side's info response. Lets dashboards distinguish instances by region without scraping /api/v1/info. |
A baseline operator dashboard typically tracks the request-rate and
error-rate per call label, plus the version gauge.
Troubleshooting¶
- Service exits at startup with a Lua error, and
pdns_pf_simulator_lua_worker_create_error_totalis non-zero on the last scrape: thelua.filepath is wrong, the file is malformed, or a required Lua module from thepdns-pf-lua-distpackage is missing. Confirm the path matches the one shipped by thepdns-pf-simulatorRPM and that the dependency RPM is installed. - Requests hang or pile up, especially with a single worker:
consider raising
lua.workers, or look for a slow query (largeverbose: 1simulation) holding up the pool. - HTTP returns 401 for the simulate / domain / codemappings
endpoints: the
api_keyslist is populated and the caller's key is missing or unknown. - NATS subjects are unreachable: the NATS goroutine only starts
when
nats.itsy.urlorNATS_URLis set. Check the startup log forNATS enabled— its absence means the service is HTTP-only.