Sentry creates separate otel context for dynamic pages when using @vercel/otel
Is there an existing issue for this?
- [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
- [X] I have reviewed the documentation https://docs.sentry.io/
- [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases
How do you use Sentry?
Sentry Saas (sentry.io)
Which SDK are you using?
@sentry/nextjs
SDK Version
8.17.0
Framework Version
next latest
Link to Sentry event
No response
SDK Setup/Reproduction Example
https://github.com/adam187/nextjs-sentry-otel-example
Steps to Reproduce
- yarn install
- yarn build
- yarn start
- curl 'http://localhost:3000'
Expected Result
All otel spans should have same trace id for single request.
Actual Result
Sentry creates own isolated scope that cause having spans from single splitted into two separate traces.
This is problematic since you can't view full trace for a single request.
Looks like it could be related to https://github.com/getsentry/sentry-javascript/pull/11625
Hi, I am trying to better understand your desired outcome. What do traces look for you, and what would you like them to look like?
Hi, I am trying to better understand your desired outcome. What do traces look for you, and what would you like them to look like?
Sorry for late reply.
The desired outcome would be to have all spans from single request assigned to same trace id. Now Sentry creates own context so all spans created by sentry and within sentry context are not assigned to original trace.
For us it's problematic since we can't see full trace by original trace id.
Hi @adam187, I talked with @lforst and there are a few things to unpack:
- In order to use Sentry with a custom OTEL instrumentation you need to follow some additional steps: https://docs.sentry.io/platforms/javascript/guides/nextjs/tracing/instrumentation/opentelemetry/#using-a-custom-opentelemetry-setup Make sure to add all of the components like the span processor, the propagator, the context manager and so on!
- We do not pick up OTEL instrumentation from Next.js pages router, because we found that it has a lot of incorrect data (see https://github.com/vercel/next.js/discussions/64723). For app router, the data emitted by Next.js is accurate.
- Our current recommendation for you, if you are only intending to use Sentry for tracing is to ditch the
@vercel/otelpackage. You will not get much more (if any) good data from it.
Hey @chargome, sorry for late replay.
The main issue here is not missing spans, I could live with that since I filter some of them myself. The main issue here is that it looks like that sentry create it's own isolated context and ignores tracing from the origin.
So if I make a request with some traceparent header (for example from load balancer)
curl 'http://localhost:3000' -H 'traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01'
Then trace id from origin (0af7651916cd43dd8448eb211c80319c) is used for next spans but not for the sentry spans.
span.spanContext().traceId 0af7651916cd43dd8448eb211c80319c 65073143ff8e8137 next.js
span.spanContext().traceId 0af7651916cd43dd8448eb211c80319c fd2126cfa6b28748 next.js
span.spanContext().traceId 343e1e0631bfb3841a90e43e1852ce66 f0ee3f56c7b50523 @sentry/node
span.spanContext().traceId 343e1e0631bfb3841a90e43e1852ce66 1e93ba38b4669365 @sentry/node
span.spanContext().traceId 0af7651916cd43dd8448eb211c80319c 7d54d9af00b36793 next.js
I wanted to check if it's working the same as in example from docs but for some reason I But I'm getting error:
▲ Next.js 14.2.5
- Local: http://localhost:3000
- Experiments (use with caution):
· instrumentationHook
✓ Starting...
○ Compiling /instrumentation ...
⨯ node:child_process
Module build failed: UnhandledSchemeError: Reading from "node:child_process" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.
Import trace for requested module:
node:child_process
./node_modules/@sentry/node/build/esm/integrations/context.js
./node_modules/@sentry/node/build/esm/index.js
✓ Ready in 2s
https://github.com/adam187/nextjs-sentry-otel-example/tree/sentry-example-otel
When I tried to use @sentry/nextjs insted of @sentry/node I got it compiled with some errors but still I don't see trace id to be propagated properly from request header.
https://github.com/adam187/nextjs-sentry-otel-example/tree/sentry-example-otel-2
Even if I explicitly add W3C propagators like
const propagator = new CompositePropagator({
propagators: [
new SentryPropagator(),
new W3CTraceContextPropagator(),
new W3CBaggagePropagator(),
],
});
I see the same effect, traceparent is reflected on next.js spans but sentry use own context and trace id. https://github.com/adam187/nextjs-sentry-otel-example/tree/sentry-example-otel-3
For now I reverted back to v7
Hi, the Sentry SDK doesn't speak the traceparent header, which is why the SDK might send disconnected traces from the rest of your OTEL setup. As a bare minimum, the SDK uses a proprietary sentry-trace header with an optional but strongly recommended baggage header. This is mostly due to historical (implementation pre-dating the wider adoption of OTEL within the ecosystem), but also technical reasons (more involved serverside sampling rules). If you have other components in your system that you want to have traced with Sentry, you need to install the Sentry SDK there too. Does this make sense?
I don't want to use Sentry to trace our whole system. We already using OTEL and W3C Tracing across our system. We're only using Sentry for error reporting from frontend part of the stack.
That's fair. You don't have to. But then you need to set up trace propagation yourself. We have documented the primitives here: https://docs.sentry.io/platforms/javascript/tracing/trace-propagation/custom-instrumentation/
That's fair. You don't have to. But then you need to set up trace propagation yourself. We have documented the primitives here: https://docs.sentry.io/platforms/javascript/tracing/trace-propagation/custom-instrumentation/
Still it doesn't look like my case, this look like propagating trace from server side to client side and I have issue with pure SSR requests and it's not the issue with propagating traces to other services with outgoing request but the fact that Sentry creates separate trace scope that is isolated from initial tracing 🤔
If you do not care about connecting errors to traces, you should be able to skip using the SentryPropagator.
We have new and improved docs on using Sentry with a custom otel setup here: https://docs.sentry.io/platforms/javascript/guides/nextjs/opentelemetry/custom-setup/
This explains what you need to set up and why. Your setup cannot work because you did not set up the SentryContextManager - without this, the Sentry SDK will not work as expected, because Sentry scope & OTEL context will not be linked correctly.
You need to use SentrySampler (or use wrapSamplingDecision in your own sampler) and SentryProagator if you want to be able to connect errors in your frontend to your backend.
@mydea Having the same issue with a next.js 14 app. We want to use Sentry for error monitoring only and use an existing instrumentation with @vercel/otel. We are aware of the issues with it, but it's still better for us since the Sentry instrumentation does not give correct data for web streams with Response (https://github.com/getsentry/sentry-javascript/issues/9633).
We've tried your suggestion above (https://docs.sentry.io/platforms/javascript/guides/nextjs/opentelemetry/custom-setup/#using-sentry-for-error-monitoring-only), but with this it still seems to escapes from next.js tracing any custom instrumentation within nerveless function with have be within the Sentry trace, rather than the next.js trace.
Is there any way to fix this? Are doing anything wrong and this should work or is it currently impossible to report errors to Sentry AND spans created within next.js functions be within the next.js trace, rather than the Sentry one?
@csshsh we'll release an update to the SDK very soon that should address all of your concerns. Right now there is no workaround except for disabling @vercel/otel which btw also produces a lot of incorrect data. (see https://github.com/vercel/next.js/pull/70908)
@csshsh we'll release an update to the SDK very soon that should address all of your concerns. Right now there is no workaround except for disabling
@vercel/otelwhich btw also produces a lot of incorrect data. (see vercel/next.js#70908)
Just to avoid misunderstandings, this update to the Sentry SDK will also allow configuring Sentry in a way so it does NOT escape from the next.js tracing?
@csshsh correct. We will very strongly depend on Next.js tracing moving forward - no escapages, except for situations where we find that Next.js spans are completely inaccurate. Note that pure Sentry users without any custom setups are a priority for us right now. Not because we don't care about the others, but because this stuff is surprisingly complex and we need to converge to a stable state step by step.
This should be solved with the latest version of the SDK. Let us know if it works. (Only exception being Next.js Pages router API routes because Next.js emits completely wrong durations for those)
I finally had some time to upgrade Sentry again, looks like it's working now as expected now 🙇