Skip to content

Ingestion reliability: SDK backoff and spool, idempotent batch, silence alert - #59

Merged
josedaniel-dev merged 1 commit into
mainfrom
feat/ingest-reliability
Oct 16, 2026
Merged

josedaniel-dev merged 1 commit into
mainfrom
feat/ingest-reliability

Conversation

@josedaniel-dev

Copy link
Copy Markdown
Collaborator

Step 8 of docs/roadmap.md.

Findings fixed: the SDK exporter retried instantly with no backoff, retried permanent 4xx, dropped silently and kept no counters; /v1/traces/batch was capped at 10/minute while the SDK flushes every 5 s, and answered 500 when a retried batch re-sent span ids already stored; nothing said a project had stopped sending.

  • SDK OTLPExporter: retries only network errors and 408/425/429/5xx with exponential backoff, jitter and Retry-After; permanent 4xx are counted as rejected; optional persistent spool (spool_dir; files 0600, unencrypted, bounded by spool_max_bytes, oldest evicted, drained oldest first, survives restarts); stats() = exported, retried, rejected, dropped, spooled, recovered, spool_evicted, pending. Existing constructor arguments and behaviour are unchanged by default (no spool).
  • Backend: /v1/traces/batch skips span ids already stored (a lost-answer retry no longer fails); its limit is now RATE_LIMIT_BATCH, default 120/minute (was a fixed 10/minute); GET /v1/ingest/health (last trace + 5 m/1 h/24 h counts per project); alert metric ingest_silence_minutes; quota and ingest alerts no longer depend on min_samples (a quota rule created in the UI with the default 10 could never fire).
  • Dashboard: a "Telemetry intake" card on Overview (fails silently); the alert form hides window/sample fields for the silence metric.
  • Manitos is untouched: its exporter already has retries, an encrypted spool and a circuit breaker.

Tests: SDK 9 new (backoff, retry classification, spool order/restart/bound/permanent reject, network errors), backend 5 new (idempotent batch, health, silence alert fire/resolve, never-sent project); backend 215 passed, SDK 46, dashboard 40, ruff/tsc/build clean. Checked in a browser on a synthetic instance: the intake card showed a 1-minute, a 2-hour and a 2-day silent project; a silence rule created with min_samples=10 opened its alert; no overflow at 390 px.

Not done: encrypting the SDK spool; sender-reported drop counters inside Observer (the SDK exposes stats() locally).

Merge note: this branch predates #58, so docs/roadmap.md and dashboard/src/i18n-en.ts will conflict with it; I will rebase whichever merges second.

…d a silence alert

SDK OTLPExporter: exponential backoff with jitter and Retry-After, retries only retryable failures,
optional persistent spool (0600, bounded, drained oldest first), stats(). /v1/traces/batch no longer
fails when a retried batch re-sends stored span ids and its limit is RATE_LIMIT_BATCH (120/minute,
it was 10 while the SDK flushes every 5 s). GET /v1/ingest/health, alert metric
ingest_silence_minutes, an intake card on Overview. Quota and ingest alerts no longer depend on
min_samples. Roadmap step 8 done.
@josedaniel-dev
josedaniel-dev force-pushed the feat/ingest-reliability branch from e7f0ae1 to 3adbe4a Compare October 16, 2026 07:58
@josedaniel-dev
josedaniel-dev merged commit c91f7c6 into main Oct 16, 2026
5 checks passed
@josedaniel-dev
josedaniel-dev deleted the feat/ingest-reliability branch October 17, 2026 01:49
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.

1 participant