sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

[v8] Multiple roots detected with manual spans

Open MrSerth opened this issue 1 year ago • 1 comments

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/browser

SDK Version

8.2.1

Framework Version

No response

Link to Sentry event

https://codeocean.sentry.io/performance/trace/ee6b9b5549414a8f83fcd71f9f24d054/

SDK Setup

Sentry.init({
  dsn: sentrySettings.data('dsn'),
  attachStacktrace: true,
  release: sentrySettings.data('release'),
  environment: sentrySettings.data('environment'),
  autoSessionTracking: true,
  tracesSampleRate: 1.0,
  replaysSessionSampleRate: 0.0,
  replaysOnErrorSampleRate: 1.0,
  integrations: [
        Sentry.browserProfilingIntegration(),
        Sentry.browserTracingIntegration(),
        Sentry.extraErrorDataIntegration(),
        Sentry.httpClientIntegration(),
        Sentry.replayIntegration(),
        Sentry.reportingObserverIntegration(),
        Sentry.sessionTimingIntegration(),
    ],
  profilesSampleRate: 1.0,
  initialScope: scope =>{
      if (current_user) {
          scope.setUser(_.omit(current_user, 'displayname'));
      }
      return scope;
  }
});

Steps to Reproduce

I am trying to add some custom transactions to my frontend code, allowing to gather further insights. With the previous v7 of the SDK, I was able to achieve that:

Bildschirmfoto 2024-05-18 um 12 46 32

As shown, the "run" transaction might last several seconds, and I want to have it separate for further analysis. In v7 code, I was manually starting a transaction. With v8, I am about to migrate to Sentry.startSpanManual with no currently active parent span, so that something formally known as "transaction" should be created.

However, my new transactions always keep the same trace ID, even when trying the forceTransaction option (see screenshot in "actual result"):

const cause = initiator.data('cause') || initiator.prop('id');
Sentry.startSpanManual({ name: cause, op: "transaction", forceTransaction: true }, span => {
    callback(span);
});

I already tried passing a new scope (similar to #12000), but without success either. Further, I am not sure what the actual expected behavior should be. When reading #11599, I got the impression that the newly observed behavior is expected ("All events happening within one route are associated with the trace from the propagation context."), but since the Sentry Saas UI still reports the "multiple root transactions" error, I am not sure about that.

Expected Result

Each transaction is shown in a dedicated trace and I can decide to start a new transaction as desired. Specifically, the "page load" and my various "run" transactions are not merged together. See my above screenshot for my expectation.

Actual Result

The initial page load and my custom transactions are grouped in the same trace. Simultaneously, I get a warning about "Multiple root transactions have been found with this trace ID.".

Bildschirmfoto 2024-05-18 um 12 40 01

MrSerth avatar May 18 '24 10:05 MrSerth

Hello,

This is "expected" behavior today, but I see what you mean.

You should be able to get the desired outcome like this - this is obv. not ideal but should be OK for now:

import * as Sentry from '@sentry/browser';

function isolatedThing() {
  return Sentry.continueTrace({ sentryTrace: '', baggage: '' }, () => {
    // inside of this we have a new trace!
    return Sentry.withActiveSpan(null, () => {
      // inside of this there is no parent span, no matter what!
      return Sentry.startSpan({ name: 'my span' }, () => {
        // do something....
      });
    });
  });
}

does this work for you? We are looking into providing a nicer API for this in a soon to follow update!

mydea avatar May 21 '24 09:05 mydea

Awesome, thank you! It took me a few days to integrate this change and finalize the upgrade to v8. Your code suggestion was very valuable to me, and indeed your code snippet solved the issue. With that method, I was able to get the desired output: A dedicated "transaction" (i.e., parent-level span) without the "Multiple root transactions" error.

Indeed, a nicer API would be well appreciated. For our use case, I extracted that part to a dedicated method, that consumes another function to be executed as a new span.

Since my question has been answered and a solution to my issue has been provided, implemented, and successfully deployed to production, I am closing this issue.

MrSerth avatar May 25 '24 21:05 MrSerth

Awesome, thank you! It took me a few days to integrate this change and finalize the upgrade to v8. Your code suggestion was very valuable to me, and indeed your code snippet solved the issue. With that method, I was able to get the desired output: A dedicated "transaction" (i.e., parent-level span) without the "Multiple root transactions" error.

Indeed, a nicer API would be well appreciated. For our use case, I extracted that part to a dedicated method, that consumes another function to be executed as a new span.

Since my question has been answered and a solution to my issue has been provided, implemented, and successfully deployed to production, I am closing this issue.

Great to hear that works!

We'll soon ship a new API startNewTrace (https://github.com/getsentry/sentry-javascript/pull/12138) that should make this much easier/nicer:

myButton.addEventListener('click', async () => {
  Sentry.startNewTrace(() => {
    Sentry.startSpan({ op: 'ui.interaction.click', name: 'fetch click' }, async () => {
      await fetch('http://example.com');
    });
  });
});

mydea avatar May 27 '24 07:05 mydea

We'll soon ship a new API startNewTrace (https://github.com/getsentry/sentry-javascript/pull/12138) that should make this much easier/nicer

That's nice, indeed! I prepared a PR in our repo already, just waiting for the next release.

MrSerth avatar May 27 '24 08:05 MrSerth