Skip to content

Commit 5d889aa

Browse files
author
Luca Forstner
committed
fix(nextjs): Use preprocessEvent hook to improve span data
1 parent a90d899 commit 5d889aa

File tree

1 file changed

+50
-52
lines changed

1 file changed

+50
-52
lines changed

packages/nextjs/src/server/index.ts

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,22 @@ export function init(options: NodeOptions): NodeClient | undefined {
241241
return null;
242242
}
243243

244+
// Next.js 13 sometimes names the root transactions like this containing useless tracing.
245+
if (event.transaction === 'NextServer.getRequestHandler') {
246+
return null;
247+
}
248+
249+
// Next.js 13 is not correctly picking up tracing data for trace propagation so we use a back-fill strategy
250+
if (typeof event.contexts?.trace?.data?.[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL] === 'string') {
251+
const traceparentData = extractTraceparentData(
252+
event.contexts.trace.data[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL],
253+
);
254+
255+
if (traceparentData?.parentSampled === false) {
256+
return null;
257+
}
258+
}
259+
244260
return event;
245261
} else {
246262
return event;
@@ -285,63 +301,45 @@ export function init(options: NodeOptions): NodeClient | undefined {
285301
),
286302
);
287303

288-
getGlobalScope().addEventProcessor(
289-
Object.assign(
290-
(event => {
291-
// Enhance route handler transactions
292-
if (
293-
event.type === 'transaction' &&
294-
event.contexts?.trace?.data?.['next.span_type'] === 'BaseServer.handleRequest'
295-
) {
296-
event.contexts.trace.data = event.contexts.trace.data || {};
297-
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';
298-
event.contexts.trace.op = 'http.server';
299-
300-
if (event.transaction) {
301-
event.transaction = stripUrlQueryAndFragment(event.transaction);
302-
}
303-
304-
// eslint-disable-next-line deprecation/deprecation
305-
const method = event.contexts.trace.data[SEMATTRS_HTTP_METHOD];
306-
const route = event.contexts.trace.data[ATTR_HTTP_ROUTE];
307-
if (typeof method === 'string' && typeof route === 'string') {
308-
event.transaction = `${method} ${route.replace(/\/route$/, '')}`;
309-
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'route';
310-
}
311-
}
312-
313-
// Next.js 13 is not correctly picking up tracing data for trace propagation so we use a back-fill strategy
314-
if (
315-
event.type === 'transaction' &&
316-
typeof event.contexts?.trace?.data?.[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL] === 'string'
317-
) {
318-
const traceparentData = extractTraceparentData(
319-
event.contexts.trace.data[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL],
320-
);
304+
client?.on('preprocessEvent', event => {
305+
// Enhance route handler transactions
306+
if (
307+
event.type === 'transaction' &&
308+
event.contexts?.trace?.data?.['next.span_type'] === 'BaseServer.handleRequest'
309+
) {
310+
event.contexts.trace.data = event.contexts.trace.data || {};
311+
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_OP] = 'http.server';
312+
event.contexts.trace.op = 'http.server';
321313

322-
if (traceparentData?.parentSampled === false) {
323-
return null;
324-
}
314+
if (event.transaction) {
315+
event.transaction = stripUrlQueryAndFragment(event.transaction);
316+
}
325317

326-
if (traceparentData?.traceId) {
327-
event.contexts.trace.trace_id = traceparentData.traceId;
328-
}
318+
// eslint-disable-next-line deprecation/deprecation
319+
const method = event.contexts.trace.data[SEMATTRS_HTTP_METHOD];
320+
const route = event.contexts.trace.data[ATTR_HTTP_ROUTE];
321+
if (typeof method === 'string' && typeof route === 'string') {
322+
event.transaction = `${method} ${route.replace(/\/route$/, '')}`;
323+
event.contexts.trace.data[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'route';
324+
}
325+
}
329326

330-
if (traceparentData?.parentSpanId) {
331-
event.contexts.trace.parent_span_id = traceparentData.parentSpanId;
332-
}
333-
}
327+
// Next.js 13 is not correctly picking up tracing data for trace propagation so we use a back-fill strategy
328+
if (
329+
event.type === 'transaction' &&
330+
typeof event.contexts?.trace?.data?.[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL] === 'string'
331+
) {
332+
const traceparentData = extractTraceparentData(event.contexts.trace.data[TRANSACTION_ATTR_SENTRY_TRACE_BACKFILL]);
334333

335-
// Next.js 13 sometimes names the root transactions like this containing useless tracing.
336-
if (event.type === 'transaction' && event.transaction === 'NextServer.getRequestHandler') {
337-
return null;
338-
}
334+
if (traceparentData?.traceId) {
335+
event.contexts.trace.trace_id = traceparentData.traceId;
336+
}
339337

340-
return event;
341-
}) satisfies EventProcessor,
342-
{ id: 'NextjsTransactionEnhancer' },
343-
),
344-
);
338+
if (traceparentData?.parentSpanId) {
339+
event.contexts.trace.parent_span_id = traceparentData.parentSpanId;
340+
}
341+
}
342+
});
345343

346344
if (process.env.NODE_ENV === 'development') {
347345
getGlobalScope().addEventProcessor(devErrorSymbolicationEventProcessor);

0 commit comments

Comments
 (0)