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

ref: Make dynamic sampling context mutable #5710

Merged
merged 42 commits into from Sep 15, 2022
Merged

Conversation

lforst
Copy link
Member

@lforst lforst commented Sep 8, 2022

Ref: #5679

This PR makes Dynamic Sampling Context in Head-SDKs mutable.

List of changes:

  • Remove our Baggage abstraction (keeping track of foreign baggage and mutability is not necessary)
  • Replace Baggage abstraction with functions that convert baggage headers into DSC and vice-versa
  • Replace getBaggage() method on the Transaction class with getDynamicSamplingContext() which doesn't freeze DSC upon retrieval
  • Refactor the adding of Sentry baggage items so that we're (almost) always adding an additional independent baggage header, in addition to any that were already there. This was done to reduce code complexity and bundle size. An exception here is in the browser where there is a case where I don't know if adding an additional header might break things.
  • Explicitly handle the case of multiple incoming baggage headers. (if there are multiple items that are named the same, last one always wins)
  • Freeze DSC in the transaction creation if DSC was provided via transactionContext.metadata.dynamicSamplingContext - used in non-head-SDKs
  • Fix extractTraceparentData so that it returns undefined (ie. "invalid") when passed an empty string - also added a test for that.

Resolves #5652

@github-actions
Copy link
Contributor

github-actions bot commented Sep 8, 2022

size-limit report 📦

Path Size
@sentry/browser - ES5 CDN Bundle (gzipped + minified) 19.52 KB (-0.04% 🔽)
@sentry/browser - ES5 CDN Bundle (minified) 60.29 KB (-0.03% 🔽)
@sentry/browser - ES6 CDN Bundle (gzipped + minified) 18.11 KB (-0.04% 🔽)
@sentry/browser - ES6 CDN Bundle (minified) 53.21 KB (-0.04% 🔽)
@sentry/browser - Webpack (gzipped + minified) 19.89 KB (-0.07% 🔽)
@sentry/browser - Webpack (minified) 64.59 KB (-0.03% 🔽)
@sentry/react - Webpack (gzipped + minified) 19.92 KB (-0.06% 🔽)
@sentry/nextjs Client - Webpack (gzipped + minified) 44.81 KB (-0.36% 🔽)
@sentry/browser + @sentry/tracing - ES5 CDN Bundle (gzipped + minified) 26.03 KB (-0.29% 🔽)
@sentry/browser + @sentry/tracing - ES6 CDN Bundle (gzipped + minified) 24.41 KB (-0.26% 🔽)

@AbhiPrasad AbhiPrasad mentioned this pull request Sep 13, 2022
10 tasks
@lforst lforst marked this pull request as ready for review September 13, 2022 16:18
Copy link
Member

@AbhiPrasad AbhiPrasad left a comment

Choose a reason for hiding this comment

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

We'll have to take care that this won't affect https://github.com/getsentry/sentry-react-native - @krystofwoldrich mind taking a look at this to see if any APIs we are changing will affect y'all?

I'll keep reading this through, gimme like an hour to think through it all

cute-kitty-best-kitty

initialProps._sentryTraceData = requestTransaction.toTraceparent();
initialProps._sentryBaggage = serializeBaggage(requestTransaction.getBaggage());
initialProps._sentryBaggage = dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext);
Copy link
Member

Choose a reason for hiding this comment

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

This logic is repeated 4x - can we extract into a helper func? Can do this in another PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

We intentionally kept it this way for the ongoing Next.js changes and said we were gonna extract duplicate logic later, since we don't know yet if extracting it now will complicate things


const newTransaction = startTransaction({
op: 'nextjs.data.server',
name: options.requestedRouteName,
...traceparentData,
metadata: {
source: 'route',
baggage,
dynamicSamplingContext: traceparentData && !dynamicSamplingContext ? {} : dynamicSamplingContext,
Copy link
Member

Choose a reason for hiding this comment

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

if we have an invalid traceparentData, do we want to even include a dynamicSamplingContext? Setting the dynamicSamplingContext to be an empty object will freeze this, which doesn't make a ton of sense to me.

We could either:
a) not freeze baggage if it comes in as an empty object (invalid - didn't have a trace_id or public_key)
b) make sure that we only define dynamicSamplingContext if traceparentData is defined. This means we still have the possibility of an empty object, but should be fine since that means the parent sdk just messed something up.

I'm leaning toward b - so I would do something like so:

...(traceparentData && dynamicSamplingContext && { dynamicSamplingContext }),

We could also construct a helper for this, since we repeat this logic in some other places.

Copy link
Member Author

Choose a reason for hiding this comment

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

The reason for this ternary here was to freeze baggage if there is a sentry-trace header, but no baggage header. The freezing is intentional and to handle requests of old SDKs correctly. I confirmed with Jan that we want to keep this behavior. Sadly, this means we can't do the thing you suggested.

In normal circumstances, it shouldn't happen that there is a baggage header with sentry- values but no sentry-trace header. This is why I didn't put any handling for that case here.

Do you have any other thoughts regarding this, otherwise I would leave it as is. Having a helper seems overkill to me for a simple if statement (even though I admit it is repeated in a lot of places).

What I can do, is add a comment where we do this to explain that DSC needs to be frozen when there is trace parent data. Wdyt?

Copy link
Member

Choose a reason for hiding this comment

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

The reason for this ternary here was to freeze baggage if there is a sentry-trace header, but no baggage header

Ahhhh I see - this makes sense. Let me try playing around with the helper to clean it up a little.

Copy link
Member

Choose a reason for hiding this comment

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

Ok I give up - I think we keep this for now then.

packages/tracing/src/browser/request.ts Show resolved Hide resolved
packages/tracing/src/browser/request.ts Outdated Show resolved Hide resolved
packages/tracing/src/browser/request.ts Outdated Show resolved Hide resolved
packages/tracing/src/transaction.ts Outdated Show resolved Hide resolved
packages/types/src/baggage.ts Show resolved Hide resolved
@AbhiPrasad AbhiPrasad merged commit 347fbe4 into master Sep 15, 2022
@AbhiPrasad AbhiPrasad deleted the lforst-mutable-dsc branch September 15, 2022 09:35
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.

Handle empty baggage header
2 participants