sentry-javascript: Can not add sentry-trace header to every fetch

Package + Version

  • [5.29.2 ] @sentry/browser
  • [ 5.29.2] @sentry/node
  • raven-js
  • raven-node (raven for node)
  • other:

Description

For this request this added Screen Shot 2021-01-12 at 22 59 13

But for next several request it is not adding

Screen Shot 2021-01-12 at 22 59 47

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (6 by maintainers)

Most upvoted comments

Hey folks - just following up on this thread.

@laygir we apologize for the delay in getting back - but we are a small team, we can only work on so much at a time. The past few months we’ve been focusing on reducing bundle size, adding support for our dynamic sampling/server-side sampling feature, and releasing SDKs for Svelte and Remix. The bundle size work was most important to us, so we’ve been purposely putting our energies toward that. That has been wrapped up, so we can now move onto other things!

Now onto the current issue. To solve this, we would have to figure out what transaction to place these requests in. It doesn’t make sense to extend our pageload or navigation transactions, because often times these requests are not part of the “page render” operation. They happen due to another actions that happens outside of it. For example, a button click or a background poll.

My question to you all then - what kind of transaction should we auto-instrument to have a trace? What should this be called, what kind of information would you like to see in it? If I had to put my horse in a race, it would be cool to get user interactions, like clicks, auto-instrumented - this is similar to the premise that you put forward @laygir. I’ll try writing up a new issue with details about this, and maybe we can scope this out here.

I would love to see user interactions auto-instrumented, although I recognise that’s probably not simple. That’s probably our main use case, though. I think there are also cases where events fire outside of the scope of the original pageload request and are not caught. An example of this might be when using something like react-query and the local cache expires, resulting in an API call.

Right now I am working around this by adding axios request/response interceptors which creates a transaction if missing:

axiosInstance.interceptors.request.use(async request => {
  try {
    const existingTransaction = Sentry.getCurrentHub().getScope()?.getTransaction();

    // Create a transaction if one does not exist in order to work around
    // https://github.com/getsentry/sentry-javascript/issues/3169
    // https://github.com/getsentry/sentry-javascript/issues/4072
    const transaction =
      existingTransaction ??
      Sentry.startTransaction({ name: `API Request: ${request.method} ${request.url}` });

    Sentry.getCurrentHub().configureScope(scope => scope.setSpan(transaction));

    (request as any).tracing = {
      transaction,
    };

    return request;
  } catch (err) {
    console.error(err);
    Sentry.captureException(err);
    return request;
  }
});

axiosInstance.interceptors.response.use(
  response => {
    (response.config as any).tracing?.transaction?.finish();
    return response;
  },
  error => {
    (error.config as any).tracing?.transaction?.finish();
    return error;
  }
);

I don’t love this approach since a group of API requests will

  1. End up in the transaction of the API request first fired, meaning the ability to search/group performance is more inconsistent
  2. Not be grouped under a single transaction that represents the original “trigger” for the API requests, making it harder to answer questions as they relate to performance

@kamilogorek can you explain how to attach next XHR / Fetch events after pageload transaction finishes?

I am getting pageload transaction logged, but I also want to metric later on xhr/fetch requests (which of course don’t have sentry-trace header cause transaction is gone).

@laygir i actually have the same problem. Only some requests are sending but not all due to current transaction.

@mmahalwy I hope that was the issue with your situation.

But I think it is not the solution… I have inserted right values in the tracingOrigins and behaviour was still the same for me.

The problem appears to be that Sentry only attaches the header if there is an ongoing transaction. Since transactions don’t keep open, not all your requests will have the header.

I guess you could work around this and create a transaction every time you are about to make a fetch request, but this is not nice considering what they called “automated instrumentation”. If I need to handle all that stuff, how is that an automated instrumentation… Marketing bs… And what they offer as APM is not an APM… Compare it with what you get from New Relic and see your self which one is an actual APM. (from backend services point of view)

I have the following issue created as this one was closed. And it is marked as bug by the Sentry team… https://github.com/getsentry/sentry-javascript/issues/4072

But still, even after 3 written assurances by email from 1 sales person and 2 times by a support person that this issue was going to be fixed in “a few weeks”, we are approaching the anniversary of it and still unresolved.

Company I’m working in is a paid customer for 5 years and because this has been an issue for us, we are not able upgrade our account because we can’t use these transactions without header as they don’t get associated with other transactions, there is no point in that…

So I’m sure there is subscription/growth attached to this problem for the product and Sentry is choosing not to fix it.

My 5 cents on this: the last few years they got some investments coming in and since then the dynamics in the company are changing and this reflects on the product obviously…

Hey there,

I’ve been trying the tracing/performance features of Sentry recently, and I noticed this behaviour on my end. Not every http requests have the sentry-trace header.

I have been in touch with Sentry support but it is taking too long, so I thought I would approach here as well.

Sentry support wrote me the following statements in two different emails:

  • “if a transaction doesn’t exist, no sentry-trace header will be attached to a request.”
  • “For the front-end side, the automatic instrumentation should create transaction to every XHR request (as long as the sampling is 100%).”

Above statements feel a bit contradictry to me, if every XHR request creates a transaction, how come the header is not attached at the time of a request.

I’ve already shared my debug logs with the support and last email received from the support is: “I’m partnering with a SDK engineer for this and I will get back to you as soon as I have an update.”

And if somehow support made a wrong statement and header is only attached if an active transaction exists and not every xhr request creates a transaction, then I want to ask how limited is the automatic instrumentation?

Do I need to manually create a transaction for a possible interaction to have it traced through frontend and backend? Isn’t there an option to create a transaction automatically when an XHR request about to happen without me manually trying to figure out if a transaction exists at the time of the request and if not create it every time?

For example on initial page load, we have about 8 api calls to our backend and sometimes 4 some times 3 out of 8 has the necessary header. Specially the first 3 calls made never has the header.

Then for example there is a button on the ui that calls an endpoint and backend rejects it. There is no trace header on the request so we are not able to follow the event to the backend. Event is visible individually for frontend and backend. But we do not have a breakdown the complete picture.

Just in case; my sampling is set to 1.0 and I’m really hoping I’m doing something wrong and there is a way to add the header to all xhr request for the given origins without doing manual work there…

I’m using the following packages:

@sentry/tracing”: “^6.13.3” “@sentry/vue”: “^6.13.3”

sentry-trace header is only attached, if there is an active transaction happening. If Sentry.getScope().getSpan() returns null (which is equivalent to transaction not being active), this operation is skipped. Your first request has the header because initial page load and page navigations are creating transactions, which finish once the operation completes.

Responsible code: https://github.com/getsentry/sentry-javascript/blob/e7e91999752281054a313532193f4c92a5ebea4f/packages/node/src/integrations/http.ts#L109-L122 https://github.com/getsentry/sentry-javascript/blob/e7e91999752281054a313532193f4c92a5ebea4f/packages/tracing/src/browser/request.ts#L173-L208