Prometheus scraping

Exposing operational metrics and counters through authenticated HTTP endpoints for Prometheus monitoring

Prometheus scraping

Radiator exposes operational counters, timing aggregations and info gauges over authenticated HTTP management endpoints over Prometheus 0.0.4. Metrics are held in memory; reads are inexpensive and non‑blocking. This means they reset at restart.

Access control & authentication

Scraping requires an HTTP management user with at least monitor privilege. Define this in the management.http.credentials block:

credentials {
    user "monitor" {
        password "monitorpassword";
        privilege monitor;
    }
}

Use HTTP Basic Auth when scraping:

curl -u monitor:monitorpassword --basic \
  http://localhost:8080/api/v1/metrics/prometheus

Endpoints

Only the Prometheus 0.0.4 text exposition format is currently provided. It is possible to get the same counters through the API endpoints as shown in the table below, but responses are JSON.

PurposePathFormat
Primary Prometheus scrape/api/v1/metrics/prometheusPrometheus 0.0.4 text
Targeted counter time series/api/v1/statistics/counters/time-series/<group>/<policy>/<name>JSON time series (internal debug / drill‑down)

Prometheus server configuration prometheus.yml snippet example:

scrape_configs:
  - job_name: "radiator-server"
    metrics_path: "/api/v1/metrics/prometheus"
    basic_auth:
      username: "monitor"
      password: "monitorpassword"
    static_configs:
      - targets: ["127.0.0.1:8080"]

Example scrape output (excerpt)

From an integration test run showing log-based counters after authentication attempts:

# TYPE radiator_build_info gauge
radiator_build_info{app="radiator",version="10.31.0",kind="development",timestamp="2025-12-12T06:00:47Z",cpu_target="aarch64-apple-darwin",branch="main",commit="abc123"} 1
# TYPE radiator_uptime_seconds gauge
radiator_uptime_seconds{service_ok="true"} 3600
# TYPE radiator_instance_info gauge
radiator_instance_info{instance_id="R01",pid="12345"} 1
# TYPE radiator_log_total counter
radiator_log_total{namespace="RADIUS UDP::AUTH_UDP",message="Radius UDP packet from unknown client"} 5
radiator_log_total{namespace="policy::BASIC_AUTH::handler::PAP",message="AAA accept"} 999
radiator_log_total{namespace="policy::BASIC_AUTH::handler::PAP::backend call::USERS_FILE",message="Backend query accepted"} 999
# TYPE radiator_total counter
radiator_total{namespace="policy::BASIC_AUTH"} 1500

Key points:

  • radiator_log_total: log message counters with hierarchical namespace (using :: separator) and message labels. The namespace represents the logging context hierarchy (e.g., server, policy, handler, backend).
  • radiator_total: aggregate counters per namespace prefix.
  • radiator_build_info: build metadata gauge.
  • radiator_uptime_seconds: time since server started.
  • radiator_instance_info: instance identification with instance_id and process ID.

High availability labels

See the high availability identifiers article for semantics of instance / cluster IDs. The radiator_instance_info gauge includes instance_id.

PromQL query examples

Query log messages by namespace prefix:

radiator_log_total{namespace=~"RADIUS UDP::.*"}

Query all messages for a specific policy:

radiator_log_total{namespace=~"policy::BASIC_AUTH::.*"}

Sum counters by handler:

sum by (namespace) (radiator_log_total{namespace=~".*::handler::.*"})

Usage guidelines

  • Frequency of scrapes should not have an impact on overall performance as long as they are less than once per second.
  • Do not expose metrics endpoints without authentication; they reveal operational structure.

Troubleshooting

SymptomLikely causeResolution
401 UnauthorizedMissing / wrong credentialsCreate user with monitor privilege
Empty or truncated outputNetwork proxy / auth failure mid-streamRetry with curl -v, inspect server logs
Counters not incrementingNo traffic hitting relevant handler/policyGenerate test load (e.g. integration script)

Push gateway (optional)

prompush is verified to work against Radiator for cases where Prometheus cannot directly scrape Radiator instances.