From 6231881f3f76f83422e01ddaa03def50d16a1ec9 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 5 Sep 2024 12:57:51 +0000 Subject: [PATCH 01/11] feat(nextjs): Give app router prefetch requests a `http.server.prefetch` op --- .../common/wrapServerComponentWithSentry.ts | 9 ++++++-- packages/nextjs/src/server/index.ts | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index e8d734a90ff3..feace8838cd3 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -39,6 +39,8 @@ export function wrapServerComponentWithSentry any> const requestTraceId = getActiveSpan()?.spanContext().traceId; const isolationScope = commonObjectToIsolationScope(context.headers); + const headersDict = context.headers ? winterCGHeadersToDict(context.headers) : undefined; + const activeSpan = getActiveSpan(); if (activeSpan) { const rootSpan = getRootSpan(activeSpan); @@ -47,9 +49,12 @@ export function wrapServerComponentWithSentry any> // We mark the root span as an app router span so we can allow-list it in our span processor that would normally filter out all Next.js transactions/spans rootSpan.setAttribute('sentry.rsc', true); - } - const headersDict = context.headers ? winterCGHeadersToDict(context.headers) : undefined; + if (headersDict?.['Next-Router-Prefetch']) { + // We mark the root span as a prefetch request + rootSpan.setAttribute('sentry.next.prefetch', true); + } + } isolationScope.setSDKProcessingMetadata({ request: { diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index 1132a6e1eed2..c05a6de1eca2 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -233,6 +233,27 @@ export function init(options: NodeOptions): NodeClient | undefined { ), ); + getGlobalScope().addEventProcessor( + Object.assign( + (event => { + if (event.type === 'transaction') { + // We set the op for transactions that we have identified as prefetch request to `http.server.prefetch` + if ( + event.contexts?.trace?.data?.['sentry.next.prefetch'] === true && + event.contexts.trace.op === 'http.server' + ) { + event.contexts.trace.op = 'http.server.prefetch'; + } + + return event; + } else { + return event; + } + }) satisfies EventProcessor, + { id: 'NextTransactionEnhancer' }, + ), + ); + getGlobalScope().addEventProcessor( Object.assign( ((event, hint) => { From 539cac3803495e873bd70214ebbcde1decd2b623 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 6 Sep 2024 12:54:00 +0000 Subject: [PATCH 02/11] Add test --- .../nextjs-15/app/page-with-prefetch/page.tsx | 8 ++++++ .../nextjs-15/app/prefetchable-page/page.tsx | 3 +++ .../nextjs-15/tests/prefetch-tracing.test.ts | 26 +++++++++++++++++++ packages/nextjs/src/server/index.ts | 6 ++--- 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx new file mode 100644 index 000000000000..aff0c25f1d9e --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx @@ -0,0 +1,8 @@ +import Link from 'next/link'; + +export const dynamic = 'force-dynamic'; + +export default async function Page() { + await new Promise(resolve => setTimeout(resolve, 500)); + return prefetchable page; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx new file mode 100644 index 000000000000..11d08ba00ed2 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return

hello

; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts new file mode 100644 index 000000000000..3250b4d508b0 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts @@ -0,0 +1,26 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/test-utils'; + +test('Should capture transactions with `http.server.prefetch` op for prefetch traces', async ({ page }) => { + const serverPrefetchTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { + return transactionEvent?.transaction === 'GET /prefetchable-page'; + }); + + const pageloadTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { + return transactionEvent?.transaction === '/page-with-prefetch'; + }); + + await page.goto(`/pageload-tracing`); + + const [serverPrefetchTransaction, pageloadTransaction] = await Promise.all([ + serverPrefetchTransactionPromise, + pageloadTransactionPromise, + ]); + + const pageloadTraceId = pageloadTransaction.contexts?.trace?.trace_id; + + expect(pageloadTraceId).toBeTruthy(); + expect(serverPrefetchTransaction.contexts?.trace?.trace_id).toBe(pageloadTraceId); + + expect(serverPrefetchTransaction.contexts?.trace?.op).toBe('http.server.prefetch'); +}); diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index c05a6de1eca2..f1d3220fb8d1 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -244,11 +244,9 @@ export function init(options: NodeOptions): NodeClient | undefined { ) { event.contexts.trace.op = 'http.server.prefetch'; } - - return event; - } else { - return event; } + + return event; }) satisfies EventProcessor, { id: 'NextTransactionEnhancer' }, ), From 6d4505f1fdc9eb607ae7108a1ac13cbfb747f65c Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 9 Sep 2024 11:35:55 +0000 Subject: [PATCH 03/11] . --- .../app/page-with-prefetch/page.tsx | 6 ++++- .../app/prefetchable-page/loading.tsx | 11 ++++++++ .../nextjs-13/app/prefetchable-page/page.tsx | 15 +++++++++++ .../tests/isomorphic/prefetch-tracing.test.ts | 14 ++++++++++ .../nextjs-15/app/prefetchable-page/page.tsx | 3 --- .../test-applications/nextjs-15/next-env.d.ts | 2 +- .../nextjs-15/tests/prefetch-tracing.test.ts | 26 ------------------- .../common/wrapServerComponentWithSentry.ts | 5 ---- packages/node/src/integrations/http.ts | 12 +++++++++ .../src/utils/parseSpanDescription.ts | 5 ++++ 10 files changed, 63 insertions(+), 36 deletions(-) rename dev-packages/e2e-tests/test-applications/{nextjs-15 => nextjs-13}/app/page-with-prefetch/page.tsx (61%) create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx similarity index 61% rename from dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx rename to dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx index aff0c25f1d9e..c58a69a3865a 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx @@ -4,5 +4,9 @@ export const dynamic = 'force-dynamic'; export default async function Page() { await new Promise(resolve => setTimeout(resolve, 500)); - return prefetchable page; + return ( + + prefetchable page + + ); } diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx new file mode 100644 index 000000000000..9d1327b1006e --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx @@ -0,0 +1,11 @@ +export default function Page() { + return

loading

; +} + +export async function generateMetadata() { + const res = (await fetch('http://example.com/')).text(); + + return { + title: res, + }; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx new file mode 100644 index 000000000000..e56b903336d9 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx @@ -0,0 +1,15 @@ +export const dynamic = 'force-dynamic'; + +export default async function Page() { + await new Promise(resolve => setTimeout(resolve, 100)); + await (await fetch('http://example.com/', { cache: 'no-cache' })).text(); + return

hello

; +} + +export async function generateMetadata() { + const res = (await fetch('http://example.com/')).text(); + + return { + title: res, + }; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts new file mode 100644 index 000000000000..691379413058 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/test-utils'; + +test('Should capture transactions with `http.server.prefetch` op for prefetch traces', async ({ page }) => { + const serverPrefetchTransactionPromise = waitForTransaction('nextjs-13', async transactionEvent => { + console.log('t', transactionEvent.transaction); + return transactionEvent?.transaction === 'GET /prefetchable-page'; + }); + + await page.goto(`/page-with-prefetch`); + + const serverPrefetchTransaction = await serverPrefetchTransactionPromise; + expect(serverPrefetchTransaction.contexts?.trace?.op).toBe('http.server.prefetch'); +}); diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx deleted file mode 100644 index 11d08ba00ed2..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return

hello

; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts index 4f11a03dc6cc..40c3d68096c2 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts deleted file mode 100644 index 3250b4d508b0..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { waitForTransaction } from '@sentry-internal/test-utils'; - -test('Should capture transactions with `http.server.prefetch` op for prefetch traces', async ({ page }) => { - const serverPrefetchTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { - return transactionEvent?.transaction === 'GET /prefetchable-page'; - }); - - const pageloadTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { - return transactionEvent?.transaction === '/page-with-prefetch'; - }); - - await page.goto(`/pageload-tracing`); - - const [serverPrefetchTransaction, pageloadTransaction] = await Promise.all([ - serverPrefetchTransactionPromise, - pageloadTransactionPromise, - ]); - - const pageloadTraceId = pageloadTransaction.contexts?.trace?.trace_id; - - expect(pageloadTraceId).toBeTruthy(); - expect(serverPrefetchTransaction.contexts?.trace?.trace_id).toBe(pageloadTraceId); - - expect(serverPrefetchTransaction.contexts?.trace?.op).toBe('http.server.prefetch'); -}); diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index feace8838cd3..a75bfa8a2659 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -49,11 +49,6 @@ export function wrapServerComponentWithSentry any> // We mark the root span as an app router span so we can allow-list it in our span processor that would normally filter out all Next.js transactions/spans rootSpan.setAttribute('sentry.rsc', true); - - if (headersDict?.['Next-Router-Prefetch']) { - // We mark the root span as a prefetch request - rootSpan.setAttribute('sentry.next.prefetch', true); - } } isolationScope.setSDKProcessingMetadata({ diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 0d5b2d4814d1..85d73ac3ef53 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -165,6 +165,10 @@ export const instrumentHttp = Object.assign( isolationScope.setTransactionName(bestEffortTransactionName); + if (isKnownPrefetchRequest(req)) { + span.setAttribute('sentry.http.prefetch', true); + } + _httpOptions.instrumentation?.requestHook?.(span, req); }, responseHook: (span, res) => { @@ -275,3 +279,11 @@ function getBreadcrumbData(request: ClientRequest): Partial Date: Mon, 9 Sep 2024 11:38:03 +0000 Subject: [PATCH 04/11] . --- packages/nextjs/src/common/wrapServerComponentWithSentry.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts index a75bfa8a2659..e8d734a90ff3 100644 --- a/packages/nextjs/src/common/wrapServerComponentWithSentry.ts +++ b/packages/nextjs/src/common/wrapServerComponentWithSentry.ts @@ -39,8 +39,6 @@ export function wrapServerComponentWithSentry any> const requestTraceId = getActiveSpan()?.spanContext().traceId; const isolationScope = commonObjectToIsolationScope(context.headers); - const headersDict = context.headers ? winterCGHeadersToDict(context.headers) : undefined; - const activeSpan = getActiveSpan(); if (activeSpan) { const rootSpan = getRootSpan(activeSpan); @@ -51,6 +49,8 @@ export function wrapServerComponentWithSentry any> rootSpan.setAttribute('sentry.rsc', true); } + const headersDict = context.headers ? winterCGHeadersToDict(context.headers) : undefined; + isolationScope.setSDKProcessingMetadata({ request: { headers: headersDict, From 51d3049f37de69e1c59cbfc8d681240df22de610 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Mon, 9 Sep 2024 11:38:39 +0000 Subject: [PATCH 05/11] . --- packages/nextjs/src/server/index.ts | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/packages/nextjs/src/server/index.ts b/packages/nextjs/src/server/index.ts index f1d3220fb8d1..1132a6e1eed2 100644 --- a/packages/nextjs/src/server/index.ts +++ b/packages/nextjs/src/server/index.ts @@ -233,25 +233,6 @@ export function init(options: NodeOptions): NodeClient | undefined { ), ); - getGlobalScope().addEventProcessor( - Object.assign( - (event => { - if (event.type === 'transaction') { - // We set the op for transactions that we have identified as prefetch request to `http.server.prefetch` - if ( - event.contexts?.trace?.data?.['sentry.next.prefetch'] === true && - event.contexts.trace.op === 'http.server' - ) { - event.contexts.trace.op = 'http.server.prefetch'; - } - } - - return event; - }) satisfies EventProcessor, - { id: 'NextTransactionEnhancer' }, - ), - ); - getGlobalScope().addEventProcessor( Object.assign( ((event, hint) => { From a955edf5cc1e1fe0811bd3023939c89cbb42d5a8 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 10 Sep 2024 08:44:10 +0000 Subject: [PATCH 06/11] . --- .../e2e-tests/test-applications/nextjs-15/next-env.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts index 40c3d68096c2..4f11a03dc6cc 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. +// see https://nextjs.org/docs/basic-features/typescript for more information. From aafa4f78cc26358e6a603237b797a49b297e1a49 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 10 Sep 2024 09:13:48 +0000 Subject: [PATCH 07/11] . --- .../nextjs-13/app/page-with-prefetch/page.tsx | 12 ------------ .../nextjs-13/app/prefetchable-page/loading.tsx | 11 ----------- .../nextjs-13/app/prefetchable-page/page.tsx | 15 --------------- .../nextjs-15/app/page-with-prefetch/page.tsx | 5 +++++ .../nextjs-15/app/prefetchable-page/loading.tsx | 5 +++++ .../nextjs-15/app/prefetchable-page/page.tsx | 5 +++++ .../tests}/prefetch-tracing.test.ts | 3 +-- packages/opentelemetry/src/spanExporter.ts | 1 + 8 files changed, 17 insertions(+), 40 deletions(-) delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx create mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx rename dev-packages/e2e-tests/test-applications/{nextjs-13/tests/isomorphic => nextjs-15/tests}/prefetch-tracing.test.ts (86%) diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx deleted file mode 100644 index c58a69a3865a..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/app/page-with-prefetch/page.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import Link from 'next/link'; - -export const dynamic = 'force-dynamic'; - -export default async function Page() { - await new Promise(resolve => setTimeout(resolve, 500)); - return ( - - prefetchable page - - ); -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx deleted file mode 100644 index 9d1327b1006e..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/loading.tsx +++ /dev/null @@ -1,11 +0,0 @@ -export default function Page() { - return

loading

; -} - -export async function generateMetadata() { - const res = (await fetch('http://example.com/')).text(); - - return { - title: res, - }; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx deleted file mode 100644 index e56b903336d9..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/app/prefetchable-page/page.tsx +++ /dev/null @@ -1,15 +0,0 @@ -export const dynamic = 'force-dynamic'; - -export default async function Page() { - await new Promise(resolve => setTimeout(resolve, 100)); - await (await fetch('http://example.com/', { cache: 'no-cache' })).text(); - return

hello

; -} - -export async function generateMetadata() { - const res = (await fetch('http://example.com/')).text(); - - return { - title: res, - }; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx new file mode 100644 index 000000000000..11fe7bf7b1da --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx @@ -0,0 +1,5 @@ +import Link from 'next/link'; + +export default function Page() { + return prefetchable page; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx new file mode 100644 index 000000000000..d650c6c1b5ae --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx @@ -0,0 +1,5 @@ +export const dynamic = 'force-dynamic'; + +export default function Page() { + return

loading

; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx new file mode 100644 index 000000000000..6b929e90bde8 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx @@ -0,0 +1,5 @@ +export const dynamic = 'force-dynamic'; + +export default function Page() { + return

hello

; +} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts similarity index 86% rename from dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts rename to dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts index 691379413058..4c1f17e1043e 100644 --- a/dev-packages/e2e-tests/test-applications/nextjs-13/tests/isomorphic/prefetch-tracing.test.ts +++ b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts @@ -2,8 +2,7 @@ import { expect, test } from '@playwright/test'; import { waitForTransaction } from '@sentry-internal/test-utils'; test('Should capture transactions with `http.server.prefetch` op for prefetch traces', async ({ page }) => { - const serverPrefetchTransactionPromise = waitForTransaction('nextjs-13', async transactionEvent => { - console.log('t', transactionEvent.transaction); + const serverPrefetchTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { return transactionEvent?.transaction === 'GET /prefetchable-page'; }); diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index 5714a3d93970..db99da18d1e2 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -345,6 +345,7 @@ function removeSentryAttributes(data: Record): Record Date: Tue, 10 Sep 2024 11:21:19 +0000 Subject: [PATCH 08/11] . --- dev-packages/e2e-tests/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index 61f859eab5c2..1baa6128694e 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -14,7 +14,7 @@ "test:prepare": "ts-node prepare.ts", "test:validate": "run-s test:validate-configuration test:validate-test-app-setups", "clean": "rimraf tmp node_modules pnpm-lock.yaml && yarn clean:test-applications", - "clean:test-applications": "rimraf test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune" + "clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune" }, "devDependencies": { "@types/glob": "8.0.0", From 344a7266ae10a978c02a76889f41fe69fae9bc4f Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 10 Sep 2024 11:24:13 +0000 Subject: [PATCH 09/11] . --- packages/node/src/integrations/http.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/integrations/http.ts b/packages/node/src/integrations/http.ts index 85d73ac3ef53..d9e5e671b702 100644 --- a/packages/node/src/integrations/http.ts +++ b/packages/node/src/integrations/http.ts @@ -285,5 +285,5 @@ function _isClientRequest(req: ClientRequest | HTTPModuleRequestIncomingMessage) */ function isKnownPrefetchRequest(req: HTTPModuleRequestIncomingMessage): boolean { // Currently only handles Next.js prefetch requests but may check other frameworks in the future. - return !!req.headers['next-router-prefetch']; + return req.headers['next-router-prefetch'] === '1'; } From 86080e81bc3301e92f17887c0988a11ef2a1c3c7 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 10 Sep 2024 11:24:50 +0000 Subject: [PATCH 10/11] no tests :( --- .../nextjs-15/app/page-with-prefetch/page.tsx | 5 ----- .../nextjs-15/app/prefetchable-page/loading.tsx | 5 ----- .../nextjs-15/app/prefetchable-page/page.tsx | 5 ----- .../nextjs-15/tests/prefetch-tracing.test.ts | 13 ------------- 4 files changed, 28 deletions(-) delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx delete mode 100644 dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx deleted file mode 100644 index 11fe7bf7b1da..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/app/page-with-prefetch/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Link from 'next/link'; - -export default function Page() { - return prefetchable page; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx deleted file mode 100644 index d650c6c1b5ae..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/loading.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export const dynamic = 'force-dynamic'; - -export default function Page() { - return

loading

; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx b/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx deleted file mode 100644 index 6b929e90bde8..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/app/prefetchable-page/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -export const dynamic = 'force-dynamic'; - -export default function Page() { - return

hello

; -} diff --git a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts b/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts deleted file mode 100644 index 4c1f17e1043e..000000000000 --- a/dev-packages/e2e-tests/test-applications/nextjs-15/tests/prefetch-tracing.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { waitForTransaction } from '@sentry-internal/test-utils'; - -test('Should capture transactions with `http.server.prefetch` op for prefetch traces', async ({ page }) => { - const serverPrefetchTransactionPromise = waitForTransaction('nextjs-15', async transactionEvent => { - return transactionEvent?.transaction === 'GET /prefetchable-page'; - }); - - await page.goto(`/page-with-prefetch`); - - const serverPrefetchTransaction = await serverPrefetchTransactionPromise; - expect(serverPrefetchTransaction.contexts?.trace?.op).toBe('http.server.prefetch'); -}); From 3e98713c1a43dc69b24347e73230fad86c5faa19 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 10 Sep 2024 13:23:18 +0000 Subject: [PATCH 11/11] . --- packages/opentelemetry/src/spanExporter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index db99da18d1e2..5714a3d93970 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -345,7 +345,6 @@ function removeSentryAttributes(data: Record): Record