Skip to content

v0.7.4

Choose a tag to compare

@github-actions github-actions released this 21 May 21:44

What's new in v0.7.4

v0.7.4 adds two new opt-in measured-energy backends to the carbon attribution stack and refreshes the documentation tree with primer pages and a restructured README. The Rust API, the daemon wire protocol, the CLI surface, and the report JSON schema are preserved byte-for-byte from v0.7.3. Operators on ARM64 (Graviton, Ampere, Cobalt 100, Apple Silicon) or on bare-metal nodes with a baseboard management controller now have a real measured path that the previous proxy fallback could not provide.

Kepler eBPF energy source

A new [green.kepler] config section activates a daemon-only scraper that reads Kepler's cumulative joule counters off the standard Prometheus /metrics endpoint, computes per-service joule deltas vs the previous scrape, and publishes measured energy-per-op coefficients. The scrape mode is selected via source (prometheus by default for the DaemonSet deployment pattern, or direct for a co-located exporter). The metric_kind knob switches between the three Kepler counter families: kepler_container_joules_total, kepler_process_package_joules_total, and kepler_process_dram_joules_total (default container). A service_mappings table ties each perf-sentinel service name to the Kepler label value identifying the same workload (container name, command, or pid depending on metric_kind).

Kepler works on ARM64 hosts where Scaphandre's RAPL sensor is unavailable, with the precision caveats from the upstream Kepler project around ARM eBPF accuracy documented in docs/LIMITATIONS.md "Kepler precision bounds". The new model tag is kepler_ebpf, the +cal calibration suffix never applies to measured spans.

New Prometheus surfaces, all label-bounded at compile time: perf_sentinel_kepler_last_scrape_age_seconds (gauge), perf_sentinel_kepler_scrape_total{status} (counter, 2 statuses), perf_sentinel_kepler_scrape_failed_total{reason} (counter, 6 reasons pre-warmed). The reason set is shared with Scaphandre because both sources hit the same six HTTP failure modes verbatim, so a single dashboard panel can union-rate them.

Redfish BMC energy source

A new [green.redfish] config section activates a daemon-only scraper that polls one or more chassis /Power resources for PowerConsumedWatts, distributes the chassis-level joules across mapped services proportional to their ops-deltas, and publishes per-service energy-per-op coefficients. Real wall-plug measurement including periphery (PSU, NIC, drives, fans), unlike Scaphandre and Kepler which see CPU and DRAM only.

Single coefficient per chassis: all services mapped to the same node receive the same per-op value. The power_path field (JSON pointer, default /PowerControl/0/PowerConsumedWatts) accommodates vendor variance. Fixtures and unit tests cover Dell iDRAC, HPE iLO, and the OpenBMC reference response shape. Multi-chassis fleets configure one entry per node in the endpoints map.

The scrape interval is clamped to [15, 3600] seconds to defend against BMC rate-limit retaliation. The ca_bundle_path field is reserved for a follow-up release. Setting it today causes the scraper to refuse to start with a clear error message, self-signed BMC certificates require a reverse proxy with publicly-signed TLS for now. IPMI is explicitly out of scope, session-token auth via /SessionService/Sessions is also out of scope, Basic auth via auth_header is the only supported credential path.

New Prometheus surfaces: perf_sentinel_redfish_last_scrape_age_seconds (gauge), perf_sentinel_redfish_scrape_total{status} (counter), perf_sentinel_redfish_scrape_failed_total{reason} (counter, 9 reasons pre-warmed, including invalid_json, path_missing, invalid_value for vendor variance).

Carbon precedence chain extended

New canonical order:

electricity_maps_api > scaphandre_rapl > kepler_ebpf > redfish_bmc
                     > cloud_specpower > io_proxy_v3 > io_proxy_v2 > io_proxy_v1

Where multiple sources are configured for the same service, the highest-fidelity one wins. Existing Scaphandre and cloud SPECpower behavior is unchanged, a service already served by Scaphandre keeps Scaphandre regardless of Kepler or Redfish being configured. The OpsSnapshotDiff per-service ops-delta tracker was extracted from score::scaphandre::ops into a shared sibling score::ops_snapshot_diff, so all four measured-energy scrapers (Scaphandre, Kepler, Redfish, cloud SPECpower) share one implementation.

Documentation refresh

  • README restructured around a TL;DR header with a documentation index and inline integration diagrams. The GreenOps section was reframed from "waste counter" to "specialized carbon calculator" with the compliance angle surfaced, and a still-frame embedded for every feature in both EN and FR.
  • New primer hubs in docs/: SCI v1.0 and energy-tooling primer landed in METHODOLOGY.md, OpenTelemetry and Prometheus primers landed in INSTRUMENTATION.md, a Sigstore primer hub landed in SUPPLY-CHAIN.md with cross-references throughout the doc tree. The workflow doc now glosses ack signature, JSONL, quality gate, and SARIF.
  • LIMITATIONS.md now carries a complete ARM64 coverage section explaining how Scaphandre RAPL, Kepler eBPF, and Redfish BMC coexist on ARM hosts, and gained an expanded RAPL coverage discussion alongside a software-only-tool accuracy note. Two new sections cover "Kepler precision bounds" and "Redfish BMC precision bounds".
  • FR doc tree had an audit pass for missing accents, anglicisms, and prose semicolons. FR README cross-references now point at FR mirrors instead of EN docs.
  • Diagrams: docs/diagrams/mmd/daemon.mmd and docs/diagrams/mmd/carbon-scoring.mmd were updated to expose Kepler and Redfish in the scraper subgraph and the energy resolution flow. The CLI-commands diagram was refreshed.

Why this is a patch and not a minor

Every externally-visible addition is opt-in. Both [green.kepler] and [green.redfish] are absent from the default config, no existing deployment changes behavior at upgrade time. The CLI subcommand surface keeps its v0.7.3 shape byte-for-byte. The report JSON schema gains no new top-level field. The co2.model enum gains two values (kepler_ebpf and redfish_bmc), the field is already documented as an open string set populated dynamically, so v0.7.3 consumers continue to parse it without changes. Numerical carbon shifts on existing workloads only occur when an operator explicitly enables Kepler or Redfish, in which case the new measured coefficient replaces the proxy fallback for the mapped services.

Verifying this release

# Binary integrity via SLSA Build L3 attestation
gh attestation verify perf-sentinel-linux-amd64 \
  --owner robintra --repo perf-sentinel

# A periodic disclosure produced by this binary
perf-sentinel verify-hash --report perf-sentinel-report.json \
  --expected-identity "https://github.com/robintra/perf-sentinel/.github/workflows/release.yml@refs/tags/v0.7.4" \
  --expected-issuer "https://token.actions.githubusercontent.com"

gh CLI 2.49 or newer required for gh attestation verify (unchanged from v0.7.2).

Full Changelog: v0.7.3...v0.7.4