Skip to content

Commit fb14590

Browse files
authored
OTEL: Ensure that RSC:1 requests get the next.route attr (#62464)
1 parent 7727c5c commit fb14590

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

packages/next/src/server/base-server.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,14 @@ export default abstract class Server<ServerOptions extends Options = Options> {
755755
): Promise<void> {
756756
await this.prepare()
757757
const method = req.method.toUpperCase()
758+
const rsc = isRSCRequestCheck(req) ? 'RSC ' : ''
758759

759760
const tracer = getTracer()
760761
return tracer.withPropagatedContext(req.headers, () => {
761762
return tracer.trace(
762763
BaseServerSpan.handleRequest,
763764
{
764-
spanName: `${method} ${req.url}`,
765+
spanName: `${rsc}${method} ${req.url}`,
765766
kind: SpanKind.SERVER,
766767
attributes: {
767768
'http.method': method,
@@ -792,7 +793,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
792793

793794
const route = rootSpanAttributes.get('next.route')
794795
if (route) {
795-
const newName = `${method} ${route}`
796+
const newName = `${rsc}${method} ${route}`
796797
span.setAttributes({
797798
'next.route': route,
798799
'http.route': route,
@@ -1728,9 +1729,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
17281729
resolvedPathname: string
17291730
): void {
17301731
const baseVaryHeader = `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE}, ${NEXT_ROUTER_PREFETCH_HEADER}`
1731-
const isRSCRequest =
1732-
req.headers[RSC_HEADER.toLowerCase()] === '1' ||
1733-
getRequestMeta(req, 'isRSCRequest')
1732+
const isRSCRequest = isRSCRequestCheck(req)
17341733

17351734
let addedNextUrlToVary = false
17361735

@@ -1895,10 +1894,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
18951894
}
18961895

18971896
// Don't delete headers[RSC] yet, it still needs to be used in renderToHTML later
1898-
const isRSCRequest =
1899-
(Boolean(req.headers[RSC_HEADER.toLowerCase()]) ||
1900-
getRequestMeta(req, 'isRSCRequest')) ??
1901-
false
1897+
const isRSCRequest = isRSCRequestCheck(req)
19021898

19031899
// If we're in minimal mode, then try to get the postponed information from
19041900
// the request metadata. If available, use it for resuming the postponed
@@ -2997,6 +2993,7 @@ export default abstract class Server<ServerOptions extends Options = Options> {
29972993
shouldEnsure: false,
29982994
})
29992995
if (result) {
2996+
getTracer().getRootSpanAttributes()?.set('next.route', pathname)
30002997
try {
30012998
return await this.renderToResponseWithComponents(ctx, result)
30022999
} catch (err) {
@@ -3474,3 +3471,10 @@ export default abstract class Server<ServerOptions extends Options = Options> {
34743471
return this.renderError(null, req, res, pathname!, query, setHeaders)
34753472
}
34763473
}
3474+
3475+
function isRSCRequestCheck(req: BaseNextRequest): boolean {
3476+
return (
3477+
req.headers[RSC_HEADER.toLowerCase()] === '1' ||
3478+
Boolean(getRequestMeta(req, 'isRSCRequest'))
3479+
)
3480+
}

test/e2e/opentelemetry/opentelemetry.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,36 @@ createNextDescribe(
333333
])
334334
})
335335

336+
it('should handle RSC with fetch in RSC mode', async () => {
337+
await next.fetch('/app/param/rsc-fetch', {
338+
...env.fetchInit,
339+
headers: {
340+
...env.fetchInit?.headers,
341+
Rsc: '1',
342+
},
343+
})
344+
345+
await expectTrace(getCollector(), [
346+
{
347+
runtime: 'nodejs',
348+
traceId: env.span.traceId,
349+
parentId: env.span.rootParentId,
350+
name: 'RSC GET /app/[param]/rsc-fetch',
351+
attributes: {
352+
'http.method': 'GET',
353+
'http.route': '/app/[param]/rsc-fetch',
354+
'http.status_code': 200,
355+
'http.target': '/app/param/rsc-fetch',
356+
'next.route': '/app/[param]/rsc-fetch',
357+
'next.span_name': 'RSC GET /app/[param]/rsc-fetch',
358+
'next.span_type': 'BaseServer.handleRequest',
359+
},
360+
kind: 1,
361+
status: { code: 0 },
362+
},
363+
])
364+
})
365+
336366
it('should handle route handlers in app router', async () => {
337367
await next.fetch('/api/app/param/data', env.fetchInit)
338368

0 commit comments

Comments
 (0)