github Institut-du-Numerique-Responsable/perf-sentinel v0.30.0

latest release: chart-v0.30.0
3 hours ago

What's new in v0.30.0

v0.30.0 is about two things a daemon lost or multiplied on their way to PerfSentinelHub. Cross-trace correlations lived only in the daemon's rolling window, so a pair that kept following each other for an afternoon left no trace once the window moved on. And an excessive_fanout whose parent span sat outside the trace got a new signature in every trace, which filled a Hub's volume one row per trace. A daemon now pushes its correlations to the Hub as episodes, and an orphan fanout keeps one signature.

One signature per fanout, whatever trace it comes from

When the parent of a burst of calls was not a captured event of the trace, the usual case since a server span is not one, the fanout detector took parent:<span id> as the finding's template. The span id differs in every trace, so each occurrence got its own signature: an acknowledgment never matched twice, the daemon's ring filled with copies of one finding, and a Hub fed by that daemon stored one row per trace until its volume was full. The template is now the most frequent template among the children, ties going to the smallest, so the same fanout yields the same signature in every trace and names the call it repeats. A fanout whose parent is in the trace keeps the parent's template, as before.

These findings change signature once. An acknowledgment taken on one of the old signatures stops matching, which costs nothing, since none of them could ever match a second time. In the lab, the fanout scenario of validate-findings passes on the release image with the other eleven.

Correlations outlive the rolling window

With [daemon.hub_export] and [daemon.correlation] both enabled, the daemon cuts each correlated pair's activity into episodes. An episode is open while the pair's last_seen advances and closes once it has stood still for min(window_minutes, 30 minutes). The daemon sends it to the Hub's /api/import/correlations when it opens, peaks, advances by a minute and closes, in batches of at most 100 episodes and 1 MiB, with the same key and source_id as the findings. A graceful shutdown closes the open episodes before the drain. No configuration key is added.

A Hub without the route answers 404 or 405, and the daemon stops pushing correlations until it restarts while findings and incidents keep flowing. An older Hub with sign-in on answers 401, which the daemon cannot tell from a wrong key, so it retries and logs. In the lab, a pair active twice around a silence lands on the Hub as two episodes, the second overlapping an incident.

examples/grafana-findings-dashboard.json gains a Correlation episodes timeline, a Correlated pairs table, a Hub incidents annotation, off by default, and a Hub source variable in its History (Hub) row.

Errors that name their cause

A transport failure in query, the scrapers and every other user of the shared HTTP client now carries its whole cause chain, so a TLS handshake against a plain HTTP port, a refused connection and a DNS failure no longer all read HTTP transport error. query exits 1 with <route>: malformed response on any 2xx body it cannot read, where query status, query correlations, query explain, query inspect and --format json printed null or an empty answer for a proxy's HTML page. jaeger-query names the URL of an answer it cannot parse and says when it is an HTML page, usually the Jaeger UI port or a proxy.

hash-bake and verify-hash --report read the report through one file handle, its size checked on that handle and the read bounded by the 64 MiB cap, so a file swapped between the check and the read can no longer be loaded past it.

Upgrade impact

  • Ship PerfSentinelHub 0.6.0 before the daemons. A daemon with both blocks enabled starts pushing correlations on upgrade. An older Hub answers 404 with sign-in off, which stops the correlation push quietly, and 401 with sign-in on, which the daemon retries and logs until the Hub is upgraded.
  • Orphan excessive_fanout findings change signature once. They show up under a new signature, and an acknowledgment taken on an old one stops matching. No other detector, normalizer or signature changes.
  • /metrics gains two label-free series, perf_sentinel_hub_export_correlations_pending (gauge) and perf_sentinel_hub_export_correlations_dropped_total (counter).
  • No configuration key is added or removed, the public API is unchanged, the embedded reference data keeps its vintages, and MSRV stays 1.99.0.

Full detail in CHANGELOG.md.

Verifying this release

# Binary integrity via SLSA build provenance attestation (Build Level 2)
gh attestation verify perf-sentinel-linux-amd64 \
  --repo Institut-du-Numerique-Responsable/perf-sentinel

# A periodic disclosure produced by this binary, with its attestation and bundle
perf-sentinel verify-hash --report perf-sentinel-report.json \
  --attestation perf-sentinel-report.intoto.jsonl --bundle perf-sentinel-report.sig \
  --expected-identity "https://github.com/Institut-du-Numerique-Responsable/perf-sentinel/.github/workflows/release.yml@refs/tags/v0.30.0" \
  --expected-issuer "https://token.actions.githubusercontent.com" \
  --verify-binary ./perf-sentinel-linux-amd64

gh CLI 2.49 or newer required for gh attestation verify. Releases up to v0.26.2 were attested under robintra/perf-sentinel and keep their own --repo and identity.

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.