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

Custom Instrumentation is Not working with New APIs in V8 #13470

Closed
3 tasks done
an-and10 opened this issue Aug 27, 2024 · 4 comments
Closed
3 tasks done

Custom Instrumentation is Not working with New APIs in V8 #13470

an-and10 opened this issue Aug 27, 2024 · 4 comments
Labels
Package: browser Issues related to the Sentry Browser SDK

Comments

@an-and10
Copy link

an-and10 commented Aug 27, 2024

Is there an existing issue for this?

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/browser

SDK Version

8.116.0

Framework Version

React SadK 8.116.0

Link to Sentry event

https://hrc-t3.sentry.io/performance/?project=4507842173861888&query=&referrer=performance-transaction-summary&showTransactions=recent&source=performance_transaction_summary&statsPeriod=14d&unselectedSeries=p100%28%29&unselectedSeries=avg%28%29

Reproduction Example/SDK Setup

Sentry Instrument.js file - we have added the sentry Intialization

Sentry.init({
  dsn: "https://[email protected]/450888",
  debug:true,
  integrations: [
    // See docs for support of different versions of variation of react router
    // https://docs.sentry.io/platforms/javascript/guides/react/configuration/integrations/react-router/
    Sentry.reactRouterV6BrowserTracingIntegration({
      useEffect,
      useLocation,
      useNavigationType,
      createRoutesFromChildren,
      matchRoutes,
    }),
    Sentry.replayIntegration(),
  ],

  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for tracing.
  tracesSampleRate: 1.0,

  // Set tracePropagationTargets to control for which URLs trace propagation should be enabled
  tracePropagationTargets: [/^\//, /^https:\/\/localhost\/api/],

  // Capture Replay for 10% of all sessions,
  // plus for 100% of sessions with an error
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});

Steps to Reproduce

  1. Custom Instrumentation: We are looking for custom instrumentation to determine the htp request, UI thread and others request in a single group of spans/transaction
    In Version7.XX> this feature was available using startTransaction and end the transaction anywhere after custom logic of code

  2. In Newer version. - With startSpan, startSpanManual, or startInActiveSpan() - all these are starting the span correctly, and ending in callback  - working fine,

Requirment:
We dont want to close the span immediately after callback end. To be precise, we want to have any callback as well.
Example: start the user journey span at one component
lets says Component 1 - startSpan()

But performing  few actives - like filling a form of 4-5 components

Want to close this span and need to have the entire user journey - HTTP request, UI, component timing, loading images resources script ,etc loading
Closing can be at component 5 .

This we are not able to achieve as callback cannot be single-line. startIdelSpan() - this is also not working.
StartInActiveSpa ()- this works fine but do not capture any http request, resources script etc.

Componet1:

const handleAddLabelClick = () => {
       console.log("handleAddLabelClick, start sentry transaction");
     captureSentryObservabilityStart();
    };

Component 5:

 const handleSave = async () => {
        // Handle Save sentry closed
     captureSentryObservabilityEnd();
    };


captureSentryObservabilityStart = () => {
 Sentry.continueTrace({ sentryTrace: '', baggage: '' }, function (){
        return Sentry.withActiveSpan(null,function(){
            parentMenuClicked = Sentry.startInactiveSpan({
                op: "menuclicked",
                name: entityName,
                attributes: {
                    entityName: entityName
                },
                forceTransaction: true,
            });
        });
}


captureSentryObservabilityEnd = () => {
 Sentry.withActiveSpan(parentMenuClicked, function(){
                childSpanOnParent = Sentry.startInactiveSpan({
                    name: "gridload",
                    description: entityPropertyName,
                    parentSpan: parentMenuClicked,
                    parentSpanId: parentMenuClicked.spanId,
                    op: "gridload"
                });
            });

}

Reference link: #12222

Expected Result

In my Transaction - it should able to track all the HTTP request , reasoucrs, script, etc

Actual Result

In my Transaction - it should able to track all the HTTP request , reasoucrs, script, etc

@github-actions github-actions bot added the Package: browser Issues related to the Sentry Browser SDK label Aug 27, 2024
@mydea
Copy link
Member

mydea commented Aug 27, 2024

So I think what I would do in this case is:

  1. End the currently active idle span (of the pageload/navigation), if there is one:
function endCurrentActiveSpan() {
  const activeSpan = Sentry.getActiveSpan();
  const rootSpan = activeSpan && Sentry.getRootSpan(activeSpan);
  if (rootSpan) {
    rootSpan.end();
  }
}

By default all new spans (e.g. http spans etc) will be attached to the currently active root span. If you want to delimit actions manually like this, I would first end the active root span to ensure we have a clean slate.

  1. Start a new idle span

As of now, you'll need to install @sentry/core and import startIdleSpan from there. We may hoist this so you can import this from @sentry/react too. Just make sure to have the same version of @sentry/core installed as @sentry/react:

import { startIdleSpan } from '@sentry/core';

// everything (e.g. http spans etc) will now be attached to this
// this will auto-end after some seconds of inactivity, or you can also manually end it at any time
// if a navigation happens this will be auto-ended as well
const rootSpan = startIdleSpan({
  name: 'span name',
});

Then you do not need to manually attach any spans to this, anything will just go to it by default.

@an-and10
Copy link
Author

Thanks for the update.
I tried with above approach,but idle transaction is getting closed with 1-2 seconds automatically.
It's not waiting for my manual closing. Hence it is not able to track other resources.
Please find the screenshot

Image
Image

@mydea
Copy link
Member

mydea commented Aug 27, 2024

Ah, I see, that's right of course. You can extend the timeouts:

startIdleSpan({ name: 'my span' }, { idleTimeout: 60000, finalTimeout: 60000, childSpanTimeout: 60000 });

Or whatever timeouts make sense to you - the defaults are 1s / 30s / 15s. The meaning of these timeouts is:

  • idleTimeout: Defines for how long we wait for any child span to be started. If no child span is started in this timeframe, the idle span is ended.
  • finalTimeout: After this time, the idle span will definitely be ended, no matter what.
  • childSpanTimeout: The max. duration a child span may run until we end the idle span

The reason we have these timeouts is that stuff in the browser can be hard to be certain about, e.g. http requests may hang or similar things, leading to never ending spans. But if you know what you're doing, you can safely extend these timeouts and manually end the span instead.

@AbhiPrasad
Copy link
Member

Closing this for clean-up. Please re-open if it still applies. Thank you!

@AbhiPrasad AbhiPrasad closed this as not planned Won't fix, can't repro, duplicate, stale Nov 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Package: browser Issues related to the Sentry Browser SDK
Projects
Archived in project
Development

No branches or pull requests

3 participants