Task/audit otel - #550
Merged
greatest0fallt1me merged 2 commits intoJul 26, 2026
Merged
Conversation
|
@annacodervibe Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before implementing, I checked the codebase and found there was no existing OTel infrastructure at all - no packages installed, no tracer setup, nothing. What did already exist and is reused here: the correlation ID system (res.locals.correlationId / getRequestId()), and the standardized error envelope pattern. Rather than inventing new versions of either, this reuses both.
There are actually 4 audit handlers, not the one the issue's file paths suggested:
GET /api/markets/:id/audit (marketAudit.ts)
GET /api/admin/audit (admin/audit.ts)
POST /api/admin/audit/search (admin/audit/search.ts)
GET /api/admin/audit/export (admin/audit/export.ts)
All 4 are instrumented.
What's new:
src/otel/tracer.ts sets up a minimal tracer using @opentelemetry/api and @opentelemetry/sdk-trace-base, exporting spans to console/stdout for now. Wiring up a real OTLP exporter to an actual tracing backend (Jaeger, Honeycomb, etc.) is a natural follow-up, not something this PR does.
src/otel/spans.ts provides startAuditSpan, endAuditSpan, and recordErrorOnSpan helpers, with correlation ID and method/path attributes set automatically.
Each of the 4 handlers now starts a span, sets relevant attributes (including things like market ID where relevant), records exceptions on failure, and ends the span with the right status code.
The export endpoint is a stream, so its span doesn't end when the handler function returns, it ends when the response stream actually finishes (covering natural completion, client disconnect, and stream errors), so span duration reflects the real export time.
Tests: 11 new tests covering span creation, attribute population, correlation ID fallback behavior, and error recording.
A note on pre-existing issues: this repo's tsc --noEmit / npm run build currently reports 119 pre-existing TypeScript errors across 20 files, completely unrelated to this change (missing exports, duplicate imports in index.ts, drizzle-orm type mismatches, etc.). I verified this by running the exact same build on main before my changes, byte-for-byte identical error count and file list. Not something I've touched or attempted to fix here, since it's out of scope for #386.
Closes #386