[WIP] fix(node): Capture Prisma v5 engine spans under the SentryTracerProvider#21867
[WIP] fix(node): Capture Prisma v5 engine spans under the SentryTracerProvider#21867andreiborza wants to merge 1 commit into
Conversation
Prisma v5 engine spans (`prisma:engine:*`, which carry the SQL `db.statement`) were minted by hijacking the OTel SDK tracer's private `_idGenerator`. The SentryTracerProvider's tracer has no `_idGenerator`, so the shim bailed and dropped every engine span, leaving only the `prisma:client:*` spans. Replace the hack with a span registry: client spans register by their span id on `spanStart`, and each v5 engine span is created under the parent it references by id via `startInactiveSpan`. Engine spans whose parent hasn't been seen yet wait in a pending buffer until a later batch registers it, reproducing the flat `parent_span_id` regrouping the OTel SDK exporter used to do. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f67d8bd. Configure here.
| createdSpan = true; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
LRU evicts parent before resolve
Medium Severity
The global prismaSpanRegistry caps at 1000 ids and evicts least-recent entries on new registrations, but pending v5 engine spans only resolve via prismaSpanRegistry.get(parent_span_id). Under concurrent Prisma load, a client parent can be evicted after spanStart yet before createEngineSpan, so engine spans stay pending or are dropped while the parent span still exists in the trace tree.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit f67d8bd. Configure here.
|
|
||
| const span = tracer.startSpan(engineSpan.name, { | ||
| kind, | ||
| links, |
There was a problem hiding this comment.
Pending engine spans silently dropped
Medium Severity
When pendingEngineSpans exceeds 1000, the oldest entries are removed with splice before parent resolution. Unresolved engine spans waiting on a parent id that is not registered yet are discarded with no creation attempt, so prisma:engine:* spans (including SQL db.statement) can be lost under burst or out-of-order dispatch.
Reviewed by Cursor Bugbot for commit f67d8bd. Configure here.
| kind: engineSpan.kind === 'client' ? SPAN_KIND.CLIENT : SPAN_KIND.INTERNAL, | ||
| startTime: engineSpan.start_time, | ||
| parentSpan, | ||
| }); |
There was a problem hiding this comment.
v5 engine span links omitted
Low Severity
The previous v5 compatibility path forwarded engineSpan.links onto created spans. The registry-based startInactiveSpan path does not map or attach links, so v5 engine spans that rely on link metadata lose cross-span references compared to the prior implementation and the v6 dispatchEngineSpan helper.
Reviewed by Cursor Bugbot for commit f67d8bd. Configure here.
size-limit report 📦
|


Prisma v5 engine spans (
prisma:engine:*, which carry the SQLdb.statement) were dropped under theSentryTracerProvider, leaving only theprisma:client:*spans in the transaction. This re-enables the Prisma v5 integration test and fixes the regression.Root cause
The v5 compatibility shim minted engine spans by hijacking the OTel SDK tracer's private
_idGeneratorto stamp the engine's exact span/trace ids, then relied on the SDK exporter regrouping spans byparent_span_idat flush. TheSentryTracerProvider's tracer has no_idGenerator(so the shim bailed out and dropped every engine span), and it assembles transactions from the live_childrentree rather than regrouping a flat list.Fix
A bounded
spanId -> Spanregistry. Client spans register onspanStart; each v5 engine span is created under the parent it references by id viastartInactiveSpan. Because v5 dispatches engine spans detached and out of order (a child can arrive before its parent), a span whose parent isn't registered yet waits in a pending buffer until a later batch registers it. This reproduces the exporter's flatparent_span_idregrouping for the provider path, and removes the fragile_idGeneratorhack.WIP / draft: stacked on #21680 to validate on CI. To be reworked into a standalone PR against
develop(the fix is provider-agnostic; the OTel SDK /openTelemetryBasicTracerProviderpath still needs validating there).