Fix: Update resource name when child span is active in store for Next.js#7000
Fix: Update resource name when child span is active in store for Next.js#7000
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #7000 +/- ##
=======================================
Coverage 84.80% 84.80%
=======================================
Files 514 514
Lines 21987 21987
=======================================
Hits 18646 18646
Misses 3341 3341 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Overall package sizeSelf size: 13.63 MB Dependency sizes| name | version | self size | total size | |------|---------|-----------|------------| | @datadog/libdatadog | 0.7.0 | 35.02 MB | 35.02 MB | | @datadog/native-appsec | 10.3.0 | 20.73 MB | 20.74 MB | | @datadog/pprof | 5.12.0 | 11.19 MB | 11.57 MB | | @datadog/native-iast-taint-tracking | 4.1.0 | 9.01 MB | 9.02 MB | | @opentelemetry/resources | 1.30.1 | 557.67 kB | 7.71 MB | | @opentelemetry/core | 1.30.1 | 908.66 kB | 7.16 MB | | protobufjs | 7.5.4 | 2.95 MB | 5.83 MB | | @datadog/wasm-js-rewriter | 5.0.1 | 2.82 MB | 3.53 MB | | @datadog/native-metrics | 3.1.1 | 1.02 MB | 1.43 MB | | @opentelemetry/api-logs | 0.208.0 | 199.48 kB | 1.42 MB | | @opentelemetry/api | 1.9.0 | 1.22 MB | 1.22 MB | | jsonpath-plus | 10.3.0 | 617.18 kB | 1.08 MB | | import-in-the-middle | 1.15.0 | 127.66 kB | 856.24 kB | | lru-cache | 10.4.3 | 804.3 kB | 804.3 kB | | @datadog/openfeature-node-server | 0.2.0 | 118.51 kB | 437.19 kB | | opentracing | 0.14.7 | 194.81 kB | 194.81 kB | | source-map | 0.7.6 | 185.63 kB | 185.63 kB | | pprof-format | 2.2.1 | 163.06 kB | 163.06 kB | | @datadog/sketches-js | 2.1.1 | 109.9 kB | 109.9 kB | | @isaacs/ttlcache | 2.1.3 | 90.79 kB | 90.79 kB | | lodash.sortby | 4.7.0 | 75.76 kB | 75.76 kB | | ignore | 7.0.5 | 63.38 kB | 63.38 kB | | istanbul-lib-coverage | 3.2.2 | 34.37 kB | 34.37 kB | | rfdc | 1.4.1 | 27.15 kB | 27.15 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB | | tlhunter-sorted-set | 0.1.0 | 24.94 kB | 24.94 kB | | shell-quote | 1.8.3 | 23.74 kB | 23.74 kB | | limiter | 1.1.5 | 23.17 kB | 23.17 kB | | retry | 0.13.1 | 18.85 kB | 18.85 kB | | semifies | 1.0.0 | 15.84 kB | 15.84 kB | | jest-docblock | 29.7.0 | 8.99 kB | 12.76 kB | | crypto-randomuuid | 1.0.0 | 11.18 kB | 11.18 kB | | ttl-set | 1.0.0 | 4.61 kB | 9.69 kB | | mutexify | 1.4.0 | 5.71 kB | 8.74 kB | | path-to-regexp | 0.1.12 | 6.6 kB | 6.6 kB | | module-details-from-path | 1.0.4 | 3.96 kB | 3.96 kB | | escape-string-regexp | 5.0.0 | 3.66 kB | 3.66 kB |🤖 This report was automatically generated by heaviest-objects-in-the-universe |
|
✅ Tests 🎉 All green!❄️ No new flaky tests detected * Fix with Cursor requires Datadog plugin ≥v2.17.0 🔗 Commit SHA: 5035e06 | Docs | Datadog PR Page | Was this helpful? Give us feedback! |
BenchmarksBenchmark execution time: 2025-12-10 15:13:57 Comparing candidate commit 5035e06 in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 292 metrics, 28 unstable metrics. |
BridgeAR
left a comment
There was a problem hiding this comment.
LGTM with minor improvements :)
…hild spans in the store
…rks with child spans
e7bd3b8 to
5035e06
Compare
….js (#7000) Changed how to store the req to reference in page load to consider child spans in the store. It now uses the identifier instance for the lookup instead of the span.
….js (#7000) Changed how to store the req to reference in page load to consider child spans in the store. It now uses the identifier instance for the lookup instead of the span.
….js (#7000) Changed how to store the req to reference in page load to consider child spans in the store. It now uses the identifier instance for the lookup instead of the span.
… memory leak PR DataDog#7000 changed #requestsBySpanId from being keyed by span objects (short-lived) to span ID Identifier objects (long-lived). The cleanup that existed in the original Map-based implementation was removed when switching to WeakMap, under the assumption that GC would handle it. However, _spanId Identifier objects live as long as the span context, which is retained by the profiler and analytics pipeline long after the request finishes. This prevents the WeakMap from releasing the IncomingMessage (with all headers, URL, Next.js metadata) for GC. Adds explicit cleanup in finish(), restoring the behavior from the original implementation that was removed in commit 5035e06. Fixes DataDog#7876 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
What does this PR do?
When OpenTelemetry TracerProvider was enabled, Next.js routes showed only HTTP method as resource name ("GET") instead of full path ("GET /api/hello").
Motivation
This is related to #1750 and escalation https://datadoghq.atlassian.net/browse/APMS-17880.
Root Cause
The Next.js plugin builds resource names in two stages:
bindStart()- Creates HTTP span with method-only resource namepageLoad()- Updates with full pathThe plugin stored requests in a WeakMap using span objects as keys:
this._requests.set(span, req).When TracerProvider enabled, OTel creates child spans (e.g., "resolve page components") that become active in async context between
bindStartandpageLoad. ThepageLoadmethod would then retrieve a different span object (the child) from storage, causing WeakMap lookup to fail since it requires an exact object identity (===).This is a change from an object-based WeakMap to ID-based Map with parent span fallback in order to handle the case where a child span is created and the context storage has changed. There is a cleanup in
finishthat will prevent memory leaks since we are now using a Map.