14 — Monitor Prometheus /metrics scrape¶
Who this is for. You run a Prometheus-based SRE stack — vanilla Prometheus, Grafana Agent, Datadog Agent in Prometheus mode, OpenTelemetry Collector with the Prometheus receiver, or anything else that speaks the standard pull protocol. You want CodeGreen's energy metrics scraped on the same cadence and stitched into the same dashboards as every other service metric.
This example stands up codegreen monitor with the Prometheus exporter on
an ephemeral port, drives a small synthetic webapp through the UDS
annotation middleware, scrapes /metrics with a tiny vendored parser, and
asserts the canonical metric names + per-route labels landed.
Quick run¶
Expected last line on Linux with prometheus_client installed:
When the optional deps are missing, the script prints
SKIP: prometheus_client not installed; pip install codegreen[prometheus]
and exits 0. The test harness accepts both.
What the example does¶
- Launches
codegreen monitor --listen-on-socket <sock> -o <jsonl> --quiet --json -i 150 --exporter prometheus --prometheus-port <random>as a subprocess. - Drives 5 HTTP requests through a stdlib
ThreadingHTTPServerplus the UDS annotation middleware from example 11. - Scrapes
http://127.0.0.1:<port>/metricswithurllib.requestand parses the Prometheus text format with ~30 lines of vendored code (noprometheus_clienttest dependency). - Calls
/healthzfor the structured JSON liveness payload. - Stops the monitor, asserts the canonical metric names appear with
host/pid/attribution_backendresource labels plus theroutelabel on request-scoped metrics, anddropped_samples == 0.
Metric catalog¶
The Prometheus sink registers the following instruments on a per-Sink
CollectorRegistry (NOT the global default — two Monitors on the same
host stay isolated):
| Metric | Kind | Unit | Labels |
|---|---|---|---|
codegreen_energy_joules_total |
Counter | J | host, pid, attribution_backend |
codegreen_power_watts |
Gauge | W | host, pid, attribution_backend |
codegreen_request_energy_joules_total |
Counter | J | + route, status |
codegreen_request_duration_seconds |
Histogram | s | + route, status |
codegreen_monitor_uptime_seconds |
Gauge | s | host, pid, attribution_backend |
codegreen_distinct_labels |
Gauge | - | host, pid, attribution_backend |
codegreen_overflow_label_count_total |
Counter | - | host, pid, attribution_backend |
codegreen_dropped_samples_total |
Counter | - | + sink |
Histogram buckets for codegreen_request_duration_seconds are configurable
via monitor.exporters.prometheus.histogram_buckets_request_duration_seconds
in codegreen/config.json (defaults: 5ms, 10ms, 25ms, 50ms, 100ms, 250ms,
500ms, 1s, 2.5s, 5s, 10s).
Compliance posture¶
- Default bind =
127.0.0.1(loopback). Settinglisten_addrto a non-loopback address emits aRuntimeWarningat start — the audit log shows the operator made an explicit choice. - Bearer-token auth via
monitor.exporters.prometheus.auth_token. When set, both/metricsand/healthzrequire anAuthorization: Bearer <token>header; comparison useshmac.compare_digest(constant-time). - Cardinality cap — labels passed to the sink are already capped by
monitor.annotation.max_labels; the__other__overflow bucket guarantees the Prometheus label-value cardinality is bounded regardless of upstream URL-PII explosions. - Resource-attribute redaction — set
monitor.exporters.prometheus.redact_resource_attrsto a list containing any ofhost,pid,attribution_backend; matching labels render as__redacted__in the exposed metrics while the actual values continue to be tracked internally. - Pull, not push — the exporter never makes outbound connections; only the scraper reaches in. No accidental data exfiltration when the endpoint is firewalled correctly.
Adapting to a real Prometheus scrape¶
# prometheus.yml
scrape_configs:
- job_name: codegreen
metrics_path: /metrics
static_configs:
- targets: ["host-running-codegreen:9464"]
# optional: bearer_token: "..."
Run the monitor:
codegreen monitor --exporter prometheus \
--prometheus-listen-addr 0.0.0.0 \
--prometheus-port 9464 \
-i 250 -o /var/log/codegreen/energy.jsonl
For shared environments add an auth_token in codegreen/config.json and
configure bearer_token in the corresponding scrape_config. Pair with a
network policy / firewall rule that only allows Prometheus's IP to reach
port 9464.