github robintra/perf-sentinel v0.5.10

latest releases: chart-v0.2.58, v0.8.12, chart-v0.2.57...
one month ago

What's new in v0.5.10

The 0.5.9 release plumbed intensity_estimated and intensity_estimation_method end-to-end on green_summary.regions[] so consumers reading the JSON output could distinguish carbon intensity values measured by Electricity Maps from those modeled by an internal estimation algorithm. The wire was complete, but the two user-facing rendering surfaces (HTML dashboard and CLI terminal) still ignored the fields, leaving operators to grep the raw JSON to tell Some(true) apart from Some(false). v0.5.10 closes that loop.

The dashboard's Regions table in the GreenOps tab gains a sixth column Estimated. Three visual states cover the full domain: an orange Estimated badge when the Electricity Maps API marked the value as estimated (hover surfaces a tooltip carrying the estimationMethod algorithm tag, e.g. TIME_SLICER_AVERAGE), a green Measured badge when the value was directly measured (hover surfaces "measured directly from the grid operator"), and a neutral dash for any row whose intensity_source is not real_time (annual, hourly, monthly_hourly profiles do not carry estimation metadata). Both badges reuse the existing palette CSS variables (--color-background-warning, --color-text-warning, --color-background-success, --color-text-success), so dark and light themes adapt automatically without extra rules. The tooltip mechanism is the native HTML title="" attribute set via setAttribute, no third-party JS, no CSS pseudo-element. The badges keep the visual language of the existing severity badges (.ps-sev-warn, .ps-gate-pass family), same padding, same border-radius, same font weight.

The CLI terminal output of print_green_summary gains a suffix on every per-region line emitted after the source: real_time field. Format: , estimated/<METHOD> when both flags are present, , estimated when the method is absent, , measured when explicitly measured, no suffix at all when the metadata is absent (older JSON reports without the field, non-Electricity Maps sources). The line layout otherwise stays identical, existing log scrapers keep matching pre-0.5.10 line shapes. The suffix passes through sanitize_for_terminal at the print sink so a hostile --input JSON cannot inject ANSI / OSC 8 / control bytes via a crafted intensity_estimation_method, matching the parity every other user-controlled field rendered by the same function already enforced.

This release also contains a small internal refactor of the Electricity Maps scraper loop. The 0.5.9 deduplication pass had pushed run_scraper_loop past the SonarCloud cognitive complexity threshold (19 vs 15 allowed). The function is split into 4 focused helpers (run_one_tick, fetch_zones, dispatch_readings, update_failure_counter) so the top-level loop stays readable while every behavioral invariant from 0.5.9 is preserved unchanged: zone-set-level consecutive_failures semantic, all-or-nothing per shared zone, partial-success publish path. Pure refactor, no observable behavior change.

The wire format is fully backward compatible. JSON and SARIF output are unchanged from 0.5.9, the new fields use #[serde(skip_serializing_if = "Option::is_none")] so existing consumers keep deserializing the breakdown without modification. GreenOps aggregates (avoidable_io_ops, IIS, waste ratio, top_offenders) are not touched. Pure rendering surface.

Added

  • Dashboard Estimated column on the green_summary.regions[] table. New JS helper buildEstimatedCell renders one of three states per row: orange Estimated badge with title="..." tooltip surfacing the estimationMethod, green Measured badge with title="..." tooltip mentioning measurement provenance, neutral dash for non-real_time sources. Both badges live alongside the existing .ps-sev-* and .ps-gate-* family in the template.
  • CSS classes .ps-badge-estimated and .ps-badge-measured in crates/sentinel-core/src/report/html_template.html. They reuse the existing palette CSS variables, so dark and light theme switches work out of the box without per-class overrides.
  • Terminal estimation suffix appended to every per-region line emitted by print_green_summary in crates/sentinel-cli/src/render.rs. Empty when the metadata is absent so existing log scrapers keep matching.
  • Pure helper format_estimation_suffix in the CLI render module. Returns Cow<'static, str> so the three constant arms ("", ", estimated", ", measured") stay zero-allocation.
  • Test fixture tests/fixtures/report_three_estimation_states.json carrying a 3-row green_summary.regions[] covering the three visual states. Drives the manual visual validation HTML and the terminal snapshot.

Changed

  • Internal: run_scraper_loop refactor. Split into run_one_tick + fetch_zones + dispatch_readings + update_failure_counter to drop SonarCloud cognitive complexity from 19 to under 15. Behavior is byte-identical, all 0.5.9 zone-set-level + all-or-nothing-per-shared-zone invariants preserved.

Behavior

  • No JSON or SARIF format change. Both already serialize the fields since 0.5.9.
  • No GreenOps aggregate change. The new metadata is read-only, never multiplied into the carbon math.
  • Backward compatible with pre-0.5.9 JSON reports: the dashboard renders a neutral dash and the terminal omits the suffix when intensity_estimated is None.
  • Defense-in-depth: intensity_estimation_method lands in the terminal via sanitize_for_terminal so a malicious --input JSON cannot inject control bytes that the API-side sanitizer would normally have stripped.

Install

Prebuilt binaries (Linux amd64 / arm64, macOS arm64, Windows amd64):

curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.5.10/perf-sentinel-linux-amd64
chmod +x perf-sentinel-linux-amd64
sudo mv perf-sentinel-linux-amd64 /usr/local/bin/perf-sentinel

Linux binaries are statically linked against musl and run on any distribution (Alpine, Debian, RHEL, Ubuntu any version) regardless of glibc version, and inside FROM scratch images.

From crates.io:

cargo install perf-sentinel

Docker:

docker run --rm -p 4317:4317 -p 4318:4318 \
  ghcr.io/robintra/perf-sentinel:0.5.10 watch --listen-address 0.0.0.0

Also available on Docker Hub: robintrassard/perf-sentinel:0.5.10.

Helm (chart 0.2.13 ships 0.5.10 as its appVersion default):

helm install perf-sentinel oci://ghcr.io/robintra/charts/perf-sentinel \
  --version 0.2.13 \
  --namespace observability --create-namespace

Verify the binary against SHA256SUMS.txt:

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

Full diff: v0.5.9...v0.5.10

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.