github robintra/perf-sentinel v0.5.14

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

What's new in v0.5.14

v0.5.13 promised in the report --help documentation that --input honored "Same format auto-detection as analyze --input (native JSON, Jaeger, Zipkin v2)". The implementation only delivered for native JSON and Zipkin v2. A Jaeger JSON export ({"data": [{"spans": [...]}]}) was misrouted to the Report-JSON parser and died with Error parsing --input as Report JSON: missing field 'analysis'. The shared helper load_report_from_input (consumed by both report and inspect) dispatched purely on the first non-whitespace byte, so any top-level { was treated as a pre-computed Report. Native event arrays and Zipkin v2 inputs (top-level [) were already accepted via JsonIngest::detect_format. Only Jaeger was broken. v0.5.14 closes that gap with a small CLI-side dispatch fix, the daemon and the scoring pipeline are untouched.

The { branch now tries serde_json::from_slice::<Report> first (the daemon snapshot fast path, succeeded short-circuits before any ingest). On parse failure the helper hands off to JsonIngest::ingest, which routes Jaeger via the existing detect_format heuristic. The trade-off is one extra full Report parse on Jaeger inputs, negligible in practice because the canonical Jaeger ingestion path is tempo / jaeger-query / analyze. The daemon snapshot pipeline curl /api/export/report | perf-sentinel report --input - keeps a single parse and identical performance to v0.5.13.

The pre-existing MAX_JSON_DEPTH cap on the Report fast path is now an explicit guard with its own dedicated error message (--input JSON exceeds maximum nesting depth of 32) rather than a silent fallthrough into the ingest fallback, so an over-deep payload exits with the right diagnostic instead of a misleading downstream error.

The error surfaced on unrecognized top-level objects is also clearer. When the input is neither a Report JSON nor a Jaeger export, report and inspect now print Error: --input top-level object is neither a pre-computed Report JSON nor a Jaeger export. Underlying error: ... instead of the misleading missing field 'analysis' text that hid the real disambiguation. Operators reading a CI log should now see what was expected without guessing.

The fix benefits inspect --input symmetrically because both subcommands consume the same helper. The docs/ci-templates/gitlab-ci.yml template's commented-out Pages section, which feeds report --input with a raw Jaeger export, becomes effectively functional with no template change required.

Changed

  • report --input and inspect --input now accept Jaeger JSON exports as documented. The shared helper load_report_from_input previously routed any top-level { straight to the Report-JSON parser, killing Jaeger inputs with missing field 'analysis'. The new dispatch tries Report first, falls back to JsonIngest (Jaeger via detect_format) on parse failure. Workaround pipelines like cat traces.jaeger.json | perf-sentinel analyze --format json | perf-sentinel report --input - are no longer needed.
  • Clearer error on unrecognized top-level objects. A bogus {-rooted input that is neither a Report JSON nor a Jaeger export now prints Error: --input top-level object is neither a pre-computed Report JSON nor a Jaeger export. Underlying error: ..., with the underlying serde / ingest message preserved on a second line.
  • Explicit MAX_JSON_DEPTH guard on the Report fast path. An over-deep payload now exits with --input JSON exceeds maximum nesting depth of 32 instead of silently falling through to the ingest fallback and producing a less-targeted error.
  • Doc-comment of Commands::Report extended with one sentence acknowledging the Report JSON snapshot path. The advertised auto-detection contract on Jaeger, Zipkin, native is unchanged because it was always the intended behavior, only the implementation rejoined the contract.

Behavior

  • Daemon snapshot pipelines unchanged. curl /api/export/report | perf-sentinel report --input - keeps the fast path. A successful serde_json::from_slice::<Report> short-circuits before the ingest fallback, so there is no extra cost on the most common path.
  • green_summary audit-trail fields flow through verbatim on the snapshot fast path. top_offenders, regions, transport_gco2, co2, and the scoring_config block introduced in v0.5.12 are deserialized straight from the daemon snapshot and rendered as-is, no re-scoring. A new test (cli_report_accepts_report_snapshot_input) pins the contract on a populated fixture.
  • Native event arrays and Zipkin v2 inputs unchanged. They were already routed correctly via the top-level [ branch and JsonIngest::detect_format. The dispatch refactor preserves that behavior with regression-guard tests.
  • No SARIF, JSON, terminal or HTML output format change. No daemon-side code touched. The fix is internal to the CLI helper, consumed by report and inspect only.

Install

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

curl -LO https://github.com/robintra/perf-sentinel/releases/download/v0.5.14/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 --version 0.5.14

Docker:

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

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

Helm (chart 0.2.17 ships 0.5.14 as its appVersion default):

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

Verify the binary against SHA256SUMS.txt:

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

Full diff: v0.5.13...v0.5.14

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.