Skip to content

Tracing: always export error and slow traces, plus launch policy docs (#474) - #476

Merged
Depo-dev merged 5 commits into
devfrom
integration/tracing-and-launch-docs
Aug 29, 2026
Merged

Tracing: always export error and slow traces, plus launch policy docs (#474)#476
Depo-dev merged 5 commits into
devfrom
integration/tracing-and-launch-docs

Conversation

@Depo-dev

Copy link
Copy Markdown
Collaborator

Carries #474 (always-export error/slow traces, API stability policy, launch checklist, rollback runbook) with test coverage added for the sampler.

#474 was merged onto this branch rather than straight into dev, matching how #469, #471 and #473 were handled.

What lands

Always-export error and slow traces (#457) — the substantive piece, and the design is right.

Head sampling decides at span start, before it can know a request will fail. A low fixed ratio therefore means the one failing trace you actually need is almost never the one kept. This fixes that in two halves:

  • recordOnlySampler returns RecordOnly instead of Drop for spans the ratio sampler would discard, so the span is still recorded
  • alwaysKeepExporter inspects each finished span and exports it if it errored or ran longer than 2s, discarding the rest

Net effect: every error and every slow request is exported regardless of ratio, while ordinary traffic still samples normally.

API stability policy (#458)docs/API_STABILITY.md: what /v1/ promises, what may change freely, what forces a /v2/, how experimental endpoints are marked, and the deprecation mechanism.

Launch checklist (#459) and rollback runbook (#460) — both as documents.

Added on top (bf4ffa0)

#474 shipped the sampler with no tests, and this logic breaks silently: a Drop decision cannot be reconsidered at export time, so reverting RecordOnly to Drop would restore exactly the behaviour the change exists to prevent, with nothing failing.

Added coverage for both halves:

Test Pins
TestAlwaysRecordSamplerNeverDrops never returns Drop, checked at ratio 0 so a surviving span proves RecordOnly kept it
TestAlwaysKeepExporter... errors kept, slow spans kept, fast successful spans discarded
boundary case a span exactly at the threshold is discarded, so > cannot drift to >=

Both assertions were verified against deliberately broken copies of the sampler — switching RecordOnly back to Drop fails the first, relaxing the comparison fails the boundary case. A passing test that cannot fail is worth nothing, so this was checked rather than assumed.

Issue status

Closed #458 by hand — the policy covers every criterion. Auto-close does not fire when the base is not the default branch.

Left open with specifics recorded on each:

Worth flagging from the rollback runbook

The author checked and found database/migrations/ has 25 forward migrations and zero .down.sql files — so no migration is reversible in any automated sense today, and a rollback across a schema change means hand-writing reverse SQL under incident pressure.

They flagged it rather than papering over it, and recommend requiring a .down.sql per migration plus expand/contract for anything not cleanly reversible. That is arguably its own issue and blocks #460.

Verification

go build, go vet, gofmt and go test ./... all pass.

Also cherry-picked the apk upgrade fix for CVE-2026-14456 from integration/launch-fixes, since this branch is off dev and would otherwise fail the same required trivy check.

adenikeakan and others added 4 commits August 27, 2026 04:35
- tracing_sampler.go: wraps the OTLP exporter and root sampler so
  every error span and every span slower than 2s is always exported,
  regardless of the configured head-sampling ratio, instead of a flat
  ratio that almost never picks the one failing request that matters
- docs/API_STABILITY.md: what /v1 promises, what counts as a breaking
  vs non-breaking change, experimental-endpoint marking, and the
  deprecation mechanism (headers + changelog); flags /v1/admin/db as
  needing an explicit stable-vs-experimental decision before freeze
- docs/LAUNCH_CHECKLIST.md + docs/ROLLBACK_RUNBOOK.md: checklist/
  runbook templates, not claimed as executed — includes a real finding
  that all 25 existing migrations are forward-only (zero .down.sql
  files), so rollback across most schema changes has no automated path
  today

Closes #457
Closes #458
Closes #459
Closes #460
Always-export error/slow traces, API stability policy, launch checklist and rollback runbook
#474 added recordOnlySampler and alwaysKeepExporter with no tests, and the
logic is easy to break silently: a Drop decision cannot be reconsidered at
export time, so reverting RecordOnly to Drop would restore the exact
behaviour the change exists to prevent — errors and slow requests vanishing
under a low sampling ratio — with nothing failing.

Covers:

- The sampler never returns Drop, tested at ratio 0 so any span surviving
  proves the RecordOnly path kept it rather than head sampling.
- The exporter keeps error spans and spans slower than slowSpanThreshold,
  and discards fast successful unsampled ones.
- A span exactly at the threshold is discarded, pinning the boundary so
  `>` cannot drift to `>=` unnoticed.

Both assertions were verified against deliberately broken copies: switching
RecordOnly back to Drop fails the first test, and relaxing the threshold
comparison fails the boundary case. Without that check a passing test tells
you nothing.
`SBOM + scan (go-api)` fails on CVE-2026-14456 — libcrypto3 3.5.7-r0, a
fixable HIGH (OpenSSL denial of service via unbounded memory). It is a
required status check, so this one finding blocks every PR in the repo,
including ones that touch nothing related.

A digest bump does not fix it: the pin here is already the current
alpine:3.22 (3.22.5, verified with `docker buildx imagetools inspect`). The
patched libcrypto3 3.5.8-r0 is published in the v3.22 package repo but no
rebuilt base image carries it yet.

`apk upgrade --no-cache` in the runtime stage picks up the patched package
while leaving the base pinned by digest, so builds stay reproducible against
a known image and still ship patched system libraries.

Verified 3.5.8-r0 is the current libcrypto3 in the alpine v3.22 main repo.
Not applied to the other Dockerfiles: only go-api is failing the scan, and
the same change elsewhere should follow its own scan evidence rather than
being copied on assumption.
@Depo-dev
Depo-dev merged commit 9e51b63 into dev Aug 29, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants