Skip to content

Commit 9abe91a

Browse files
authored
fix: update resource name when child span is active in store for Next.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.
1 parent d562791 commit 9abe91a

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

packages/datadog-plugin-next/src/index.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ const errorPages = new Set(['/404', '/500', '/_error', '/_not-found', '/_not-fou
1010

1111
class NextPlugin extends ServerPlugin {
1212
static id = 'next'
13+
#requestsBySpanId = new WeakMap()
1314

1415
constructor (...args) {
1516
super(...args)
16-
this._requests = new WeakMap()
1717
this.addSub('apm:next:page:load', message => this.pageLoad(message))
1818
}
1919

@@ -35,7 +35,9 @@ class NextPlugin extends ServerPlugin {
3535

3636
analyticsSampler.sample(span, this.config.measured, true)
3737

38-
this._requests.set(span, req)
38+
// Store request by span ID to handle cases where child spans are activated
39+
const spanId = span.context()._spanId
40+
this.#requestsBySpanId.set(spanId, req)
3941

4042
return { ...store, span }
4143
}
@@ -89,7 +91,13 @@ class NextPlugin extends ServerPlugin {
8991
if (!store) return
9092

9193
const span = store.span
92-
const req = this._requests.get(span)
94+
95+
const spanId = span.context()._spanId
96+
const parentSpanId = span.context()._parentId
97+
98+
// Try current span first, then parent span.
99+
// This handles cases where pageLoad runs in a child span context
100+
const req = this.#requestsBySpanId.get(spanId) ?? this.#requestsBySpanId.get(parentSpanId)
93101

94102
// safeguard against missing req in complicated timeout scenarios
95103
if (!req) return

packages/datadog-plugin-next/test/index.spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,35 @@ describe('Plugin', function () {
277277
.get(`http://127.0.0.1:${port}/api/hello/world`)
278278
.catch(done)
279279
})
280+
281+
it('should handle child spans and still find the request object', done => {
282+
agent
283+
.assertSomeTraces(traces => {
284+
const spans = traces[0]
285+
286+
const nextRequestSpan = spans.find(span => span.name === 'next.request')
287+
assert.ok(nextRequestSpan, 'next.request span should exist')
288+
289+
assert.strictEqual(nextRequestSpan.resource, 'GET /api/hello/[name]')
290+
assert.strictEqual(nextRequestSpan.meta['next.page'], '/api/hello/[name]')
291+
assert.strictEqual(nextRequestSpan.meta['http.method'], 'GET')
292+
assert.strictEqual(nextRequestSpan.meta['http.status_code'], '200')
293+
294+
const webRequestSpan = spans.find(span => span.name === 'web.request')
295+
assert.ok(webRequestSpan, 'web.request span should exist')
296+
assert.strictEqual(webRequestSpan.resource, 'GET /api/hello/[name]')
297+
298+
const childSpan = spans.find(span => span.name === 'child.operation')
299+
assert.ok(childSpan, 'child span should exist')
300+
assert.strictEqual(childSpan.parent_id.toString(), nextRequestSpan.span_id.toString())
301+
})
302+
.then(done)
303+
.catch(done)
304+
305+
axios
306+
.get(`http://127.0.0.1:${port}/api/hello/world?createChildSpan=true`)
307+
.catch(done)
308+
})
280309
})
281310

282311
describe('for pages', () => {

packages/datadog-plugin-next/test/pages/api/hello/[name].js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
export default (req, res) => {
44
const tracer = require('../../../../../dd-trace')
5+
6+
if (req.query.createChildSpan === 'true') {
7+
const childSpan = tracer.startSpan('child.operation', {
8+
childOf: tracer.scope().active()
9+
})
10+
11+
tracer.scope().activate(childSpan, () => {
12+
childSpan.finish()
13+
})
14+
}
15+
516
const span = tracer.scope().active()
617
const name = span && span.context()._name
718

0 commit comments

Comments
 (0)