Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nextjs): Use Next.js generated serverside spans for app router rendering #12729

Open
wants to merge 25 commits into
base: develop
Choose a base branch
from

Conversation

lforst
Copy link
Member

@lforst lforst commented Jul 2, 2024

Previously when we attempted to use the OTEL tracing provided by Next.js we faced data quality issues. The problem was that we used to look at the data holistically and not in isolation. We discovered that certain data provided by Next.js is actually more accurate than the data we collect, in particular the data we collect for app router SSR requests.

With this PR we start using OTEL data for app router SSR requests. We do this by allow-listing spans created for these requests by Next.js so that we are only capturing these spans/traces.

With this PR, we're starting to use our/otel's HTTP instrumentation (only for app router SSR requests!) so we can capture the most accurate data.

There are a few gotchas:

  • Next.js emits multiple "GET /bla/bla" spans when middleware is used. We are renaming those to avoid collisions with our own HTTP spans.
  • Our HTTP instrumentation doesn't capture parameterized routes as span names and Next.js does. We will grab the parameterized routes off the Next.js spans and hoist them into our own HTTP spans.

Traces look like this now:

Screenshot 2024-07-05 at 12 32 54

@lforst lforst marked this pull request as ready for review July 4, 2024 07:33
@lforst
Copy link
Member Author

lforst commented Jul 4, 2024

This is ready for review, just need to figure out why 1 e2e test is failing.

Copy link
Member

@mydea mydea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty cool!

Copy link
Member

@chargome chargome left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Does this have any effect on page routes as well?

Copy link
Contributor

github-actions bot commented Jul 4, 2024

size-limit report 📦

Path Size
@sentry/browser 22.28 KB (0%)
@sentry/browser (incl. Tracing) 33.43 KB (0%)
@sentry/browser (incl. Tracing, Replay) 69.18 KB (0%)
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 62.51 KB (0%)
@sentry/browser (incl. Tracing, Replay with Canvas) 73.24 KB (0%)
@sentry/browser (incl. Tracing, Replay, Feedback) 85.87 KB (0%)
@sentry/browser (incl. Tracing, Replay, Feedback, metrics) 87.73 KB (0%)
@sentry/browser (incl. metrics) 26.57 KB (0%)
@sentry/browser (incl. Feedback) 38.93 KB (0%)
@sentry/browser (incl. sendFeedback) 26.9 KB (0%)
@sentry/browser (incl. FeedbackAsync) 31.52 KB (0%)
@sentry/react 25.02 KB (0%)
@sentry/react (incl. Tracing) 36.46 KB (0%)
@sentry/vue 26.39 KB (0%)
@sentry/vue (incl. Tracing) 35.29 KB (0%)
@sentry/svelte 22.41 KB (0%)
CDN Bundle 23.5 KB (0%)
CDN Bundle (incl. Tracing) 35.19 KB (0%)
CDN Bundle (incl. Tracing, Replay) 69.29 KB (0%)
CDN Bundle (incl. Tracing, Replay, Feedback) 74.48 KB (0%)
CDN Bundle - uncompressed 68.97 KB (0%)
CDN Bundle (incl. Tracing) - uncompressed 103.98 KB (0%)
CDN Bundle (incl. Tracing, Replay) - uncompressed 214.38 KB (0%)
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 227.09 KB (0%)
@sentry/nextjs (client) 36.35 KB (0%)
@sentry/sveltekit (client) 34.07 KB (0%)
@sentry/node 130.77 KB (+0.01% 🔺)
@sentry/node - without tracing 91.79 KB (+0.01% 🔺)
@sentry/aws-serverless 116.96 KB (0%)

@lforst
Copy link
Member Author

lforst commented Jul 5, 2024

@mydea @chargome This grew pretty big in changes ever since you reviewed last. Feel free to give this another pass so I don't merge any crap.

@lforst lforst requested review from mydea and chargome July 5, 2024 10:37
},
{
// This comes with the risk of tests leaking into each other but the tests run quite slow so we should parallelize
workers: '100%',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤞

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my thought was: If the tests leak, the tests are bad anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

}
});

client?.on('spanEnd');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
client?.on('spanEnd');

I guess this is a leftover? 😅

client?.on('beforeSampling', ({ spanAttributes, spanName, parentSampled, parentContext }, samplingDecision) => {
// We "whitelist" the "BaseServer.handleRequest" span, since that one is responsible for App Router requests, which are actually useful for us.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// We "whitelist" the "BaseServer.handleRequest" span, since that one is responsible for App Router requests, which are actually useful for us.
// We allowlist the "BaseServer.handleRequest" span, since that one is responsible for App Router requests, which are actually useful for us.

Copy link
Member

@mydea mydea left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

const spanAttributes = spanToJSON(span).data;

// What we do in this glorious piece of code, is hoist any information about parameterized routes from spans emitted
// by Next.js via the `next.route` attribure, up to the transaction by setting the http.route attribute.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// by Next.js via the `next.route` attribure, up to the transaction by setting the http.route attribute.
// by Next.js via the `next.route` attribute, up to the transaction by setting the http.route attribute.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants