Product releases, monitoring know-how and behind-the-scenes notes from the Sentrinel team.
A Django SDK with no runtime dependencies, tested from Django 3.1 to 5.2 — and the two bugs that only appeared once we pointed it at a real API.
Our setup command pointed at a checkout of a private repo. Fixing it turned out to be less about packaging than about where the API key lives.
An MCP server and a CLI that hand Claude Code, Codex and friends your issues, logs and traces — on a key that can see one app and do nothing else.
A key inside a phone, on a database host and in an agent's config each leak differently. Now each can only do its own job — and existing keys keep working.
Our durable ingest log was deleted out from under us and the fallback made things slower, not safer. Ingest now fails over in both directions — and skips what it just watched fail.
A 502 carries no CORS headers, so the browser blames the wrong layer. What we found underneath, and why any origin may now call the API without weakening the session.
/health said ok while every ClickHouse query failed to authenticate. Where the user went, why 'degraded' is not 'down', and what /health reports now.
Requests, logs, errors, traces and replays each store the user they belonged to, instead of finding out by joining back later — because the join gets shorter as data ages out.
Fifty user ids on one route must be one endpoint, and a six-letter English word must not become a wildcard. The rule that keeps the endpoint list countable.
Wait events sampled every second, blocking chains, the queries that own your CPU, and bloat — from a collector you run next to the database, on a key that can send nothing else.
Crash-free sessions and users per release, crashes that survive the crash, app start and frozen frames, and events on the phone that line up with the backend.
'Why was it slow?' is a trace. 'What did it cost?' is a metric. Priced GenAI spans answer the first per call; counters answer the second per model, per customer, per month.
Reading one header inside an afterResponse hook made every typed route lose its telemetry. Elysia's lazy context, and the fix that had to be by identity, not by value.
Tracing says why a call was slow. It cannot say what it cost. Counters, gauges and histograms that fold in-process, so recording a metric per token is a normal thing to do.
A rolling buffer that uploads only when something breaks, masked by default — and the two silent bugs we hit building it.
Real-time monitoring, crash reporting and a trace that starts on the phone and continues into your backend.
Adding production-ready monitoring to any JavaScript or TypeScript backend, in about five minutes.