github robintra/perf-sentinel v0.3.0

latest releases: chart-v0.2.48, v0.8.3, chart-v0.2.47...
one month ago

perf-sentinel v0.3.0

Major release focused on carbon scoring reliability, ecosystem coverage, and two new subcommands. This is the largest release since v0.2.0 and represents the Phase 5 work tracked in the roadmap (carbon reliability + ecosystem expansion). 10 commits between v0.2.3 and v0.3.0, 1012 tests passing (up from 476 at v0.2.3).

Highlights

  • Carbon scoring precision ladder. Six energy backends now coexist with a clear precedence: electricity_maps_api (real-time grid intensity via opt-in HTTPS API) > scaphandre_rapl (per-process RAPL on Linux bare metal) > cloud_specpower (CPU% + SPECpower interpolation for AWS / GCP / Azure VMs, ~180 instance types embedded from the Cloud Carbon Footprint coefficient tables) > io_proxy_v3 (monthly x hourly profiles for 4 regions) > io_proxy_v2 (hourly profiles for 30+ regions) > io_proxy_v1 (flat annual, universal fallback). All six can be mixed in the same run; the top-level co2.model tag reflects the highest-precision source seen.
  • SCI v1.0 alignment (ISO/IEC 21031:2024). Carbon estimates now follow the Software Carbon Intensity specification from the Green Software Foundation, standardized as ISO/IEC 21031:2024. Total is (E x I) + M [+ T] summed over analyzed traces, with embodied carbon M = traces * embodied_per_request_gco2 and optional network transport T for cross-region HTTP calls (default 0.04 kWh/GB, per Mytton, Lunden & Malmodin, J. Industrial Ecology 2024). Every CarbonEstimate carries a { low, mid, high } confidence interval (2x multiplicative) and a methodology tag so downstream consumers can tell SCI-numerator values from per-R intensity values.
  • Multi-region scoring. OTel cloud.region attribute is read per span; scores are bucketed by region and returned as green_summary.regions[] sorted by co2_gco2 descending. Per-service overrides are available via [green.service_regions]. 30+ cloud regions now have embedded hourly profiles sourced from ENTSO-E Transparency Platform and national TSOs (RTE eCO2mix for France, Fraunhofer ISE energy-charts.info for Germany, National Grid ESO Carbon Intensity API for the UK, EirGrid / TenneT / Svenska Kraftnat / Elia / Fingrid / Terna / REE / PSE / Statnett for the rest of Europe), EIA Open Data API for US balancing authorities (PJM, CAISO, BPA), Hydro-Quebec for Canada, and AEMO NEM / OpenNEM for Australia.
  • Per-operation energy coefficients. The proxy carbon model now weights energy per I/O operation by type: SQL SELECT 0.5x, INSERT/UPDATE 1.5x, DELETE 1.2x, HTTP payload size tiers (small <10 KB 0.8x, medium 10 KB-1 MB 1.2x, large >1 MB 2.0x). Coefficients sourced from Xu et al. (VLDB 2010) and Tsirogiannis et al. (SIGMOD 2010) foundational DBMS energy benchmarks, cross-validated against Siddik et al. DBJoules (2023) per-operation measurement study that confirmed 7-38% inter-operation variance.
  • Three new detectors. chatty_service (too many HTTP outbound calls per trace), pool_saturation (sweep-line peak concurrency detection for connection pool contention), and serialized_calls (Weighted Interval Scheduling DP for parallelizable sibling spans). Seven detectors now run per trace, up from four.
  • Interpretation bands. io_intensity_score and io_waste_ratio ship with a stable healthy / moderate / high / critical classification, rendered as colored parentheticals in the CLI and as *_band fields in the JSON report. Thresholds are anchored on the detector constants (the N+1 detector's CRITICAL_OCCURRENCE_THRESHOLD and Config::default().n_plus_one_threshold) via drift-guard tests that fail at build time if either side moves without the other.

New subcommands

  • perf-sentinel tempo (feature: tempo, on by default). Query a Grafana Tempo HTTP API for post-hoc trace analysis, either by trace ID or by service + lookback window. Fetches OTLP protobuf, decodes via prost, and runs the standard analysis pipeline. Supports --format text|json|sarif and --ci quality-gate mode. Dedicated 64 MiB body cap (MAX_TRACE_BODY_BYTES) for realistic traces with hundreds of spans.
  • perf-sentinel calibrate. Tune the proxy model's energy-per-op coefficients from real RAPL / wattmeter measurements. Correlates a trace file with an energy CSV (power_watts or energy_kwh) by service and time window, writes a calibration TOML that the main config loads via [green] calibration_file. Model tag gains a +cal suffix when active (e.g. io_proxy_v2+cal). Energy CSV is capped at 64 MiB.

Breaking changes

  • CarbonEstimate and CarbonReport restructured for SCI v1.0: CarbonContext.scaphandre_snapshot renamed to energy_snapshot (now a HashMap<String, EnergyEntry> carrying both the coefficient and the model tag). CarbonEstimate gains sci_numerator_with_model / operational_ratio_with_model constructors; the pre-existing sci_numerator / operational_ratio still work. No compat shim.
  • [green] region renamed to [green] default_region in .perf-sentinel.toml. Legacy flat name still loads with a deprecation warning.
  • New JSON fields on the report: green_summary.io_waste_ratio_band, top_offenders[].io_intensity_band, green_impact.io_intensity_band, plus the structured co2 object with low / mid / high / model / methodology, and the green_summary.regions[] per-region breakdown. Downstream consumers should ignore unknown fields. See the stability contract in docs/LIMITATIONS.md#score-interpretation.

Observability, performance, and hardening

  • Cognitive complexity reduction. Nine functions flagged by SonarCloud's rust:S3776 rule were split into named helpers without behavioral change: compute_carbon_report (160 → below 15, extracted into 9 span/region/model helpers plus three supporting structs), load_custom_profiles, validate_cloud_services, extract_exe_label, detect_pool_saturation, longest_non_overlapping, validate_green, parse_energy_csv, parse_iso8601_utc_to_ms. 1012 tests still green, zero clippy warnings under -D warnings + clippy::pedantic.
  • Performance polish. daemon::build_tick_ctx returns Cow<CarbonContext> and borrows the base context when no scraper produced fresh data (no per-tick clone in the common case). daemon::apply_sampling keys its decision cache on a u64 FNV-1a hash instead of a String clone (zero heap allocations for cache keys on bursts). score::count_endpoint_stats merges its double-probe HashMap pass into a single span loop via a last_seen_trace sentinel. score::cloud_energy::scraper parallelizes per-service Prometheus CPU% queries via tokio::task::JoinSet (1024 services at 20 ms used to serialize to ~20 s, now collapses to a single tail latency).
  • Three new Prometheus metrics: perf_sentinel_service_io_ops_total{service} (per-service op counter feeding the scraper snapshot-diff path), perf_sentinel_scaphandre_last_scrape_age_seconds, perf_sentinel_cloud_energy_last_scrape_age_seconds.
  • Daemon shutdown hygiene. Ctrl-C now aborts all spawned tasks (gRPC, HTTP, JSON socket, Scaphandre scraper, cloud energy scraper, Electricity Maps scraper) before draining the window, so stray tracing::error! lines do not leak after the "Shutting down" message.
  • Security. Calibrate energy CSV capped at 64 MiB to prevent local DoS. Three unsafe { std::env::remove_var } blocks removed from config.rs tests via env-lookup dependency injection (sentinel-core is back to zero unsafe blocks). Predictable /tmp test paths replaced with tempfile::TempDir (symlink-TOCTOU safe, auto-cleanup on drop). daemon::run_json_socket gains a symlink pre-check so a local attacker cannot point the socket path at a victim file. ingest_from_tempo endpoint validator now rejects @ only in the authority section (not in the path or query string) so ?owner=foo%40example.com style URLs are accepted.
  • RUSTSEC-2026-0097 (rand unsound). rand bumped from 0.9.2 to 0.9.3 (which is in the patched range >=0.9.3, <0.10.0). A second rand 0.8.5 entry remains in Cargo.lock as an optional subdep of ratatui-termwiz (a termwiz backend perf-sentinel never activates, we use crossterm), documented as non-applicable in audit.toml at the repo root with the full exposure analysis. perf-sentinel cannot trigger the unsoundness regardless: we use tracing_subscriber::fmt() without a custom logger, so none of the five UB preconditions can be satisfied.
  • Test coverage. 476 tests at v0.2.3, 1012 at v0.3.0 (+536). The five network-facing scrapers (daemon, tempo, cloud_energy, electricity_maps, scaphandre) gained mock-HTTP integration coverage in this release: happy path, 4xx / 5xx handling, malformed bodies, timeouts, body-cap enforcement, graceful abort on invalid URI.

Standards and data sources

perf-sentinel's carbon estimates now rest on an auditable chain of public standards, reference datasets, and peer-reviewed methodology:

Standard / specification

Reference datasets

  • Cloud Carbon Footprint (CCF): annual grid intensity per cloud region, per-provider PUE values, and SPECpower coefficient tables (~180 instance types) for the cloud_specpower energy backend.
  • Electricity Maps: annual average intensities for 30+ regions (2023-2024) used as the io_proxy_v1 baseline, plus the real-time API (electricity_maps_api backend).
  • ENTSO-E Transparency Platform: hourly generation and load data used to derive the monthly x hourly profiles for European bidding zones (FR, DE, GB, IE, NL, SE, BE, FI, IT, ES, PL, NO).
  • National TSOs: RTE eCO2mix (France), Fraunhofer ISE energy-charts.info (Germany), National Grid ESO Carbon Intensity API (UK), EIA Open Data API (US PJM / CAISO / BPA), Hydro-Quebec annual reports (Canada), AEMO NEM / OpenNEM (Australia).
  • Scaphandre: per-process Intel / AMD RAPL power measurement, scraped via its Prometheus endpoint when the [green.scaphandre] section is configured.

Academic methodology

  • Xu et al., Energy-Efficient Query Processing, VLDB 2010. Foundational DBMS per-operation energy benchmark.
  • Tsirogiannis et al., Analyzing the Energy Efficiency of a Database Server, SIGMOD 2010. Companion benchmark establishing verb-level coefficients.
  • Siddik et al., DBJoules: Towards Understanding the Energy Consumption of Database Management Systems, 2023. Confirms 7-38% inter-operation variance across verbs, cross-validation for the per_operation_coefficients feature.
  • Guo et al., Energy-efficient Database Systems: A Systematic Survey, ACM Computing Surveys 2022. Overview of the field.
  • IDEAS 2025 framework: real-time energy estimation model for SQL queries, referenced as the direction of travel for future calibrate improvements.
  • Mytton, Lunden & Malmodin, Estimating electricity usage of data transmission networks, Journal of Industrial Ecology 2024. Source for the 0.04 kWh/GB default on the optional include_network_transport term; the paper's 0.03-0.06 kWh/GB range is the origin of the configurable network_energy_per_byte_kwh field.
  • Boavizta API / HotCarbon 2024: bottom-up server lifecycle embodied carbon model, referenced for the embodied_per_request_gco2 default calibration.

These references are enumerated with inline citations in crates/sentinel-core/src/score/carbon.rs (top-level doc comment) and in crates/sentinel-core/src/score/carbon_profiles.rs (per-region source comments on every profile entry). The exhaustive per-region citation list is in docs/design/05-GREENOPS-AND-CARBON.md.

Install

# Prebuilt binaries (Linux amd64 / arm64, macOS arm64, Windows amd64)
curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.3.0/perf-sentinel-linux-amd64
chmod +x perf-sentinel-linux-amd64
sudo mv perf-sentinel-linux-amd64 /usr/local/bin/perf-sentinel
# From crates.io
cargo install perf-sentinel
# Docker
docker pull robintrassard/perf-sentinel:0.3.0

Also available on GHCR: ghcr.io/robintra/perf-sentinel:0.3.0

Verify the binary against SHA256SUMS.txt:

curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.3.0/SHA256SUMS.txt
sha256sum -c SHA256SUMS.txt --ignore-missing

Full changelog

Diff against the previous release: v0.2.3...v0.3.0. 10 commits, covering Phase 5a through Phase 5g plus the SonarCloud refactor and RUSTSEC patch.

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.