-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
feat(tracing): Add initial tracestate
header handling
#3909
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
feat(tracing): Add initial tracestate
header handling
#3909
Conversation
a3be155
to
3bf477f
Compare
size-limit report
|
const base64String = 'RG9ncyBhcmUgZ3JlYXQh'; | ||
|
||
test('converts to valid base64', () => { | ||
expect(BASE64_REGEX.test(unicodeToBase64(unicodeString))).toBe(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this assertion redundant when we already test for equality in the next lines?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The equality test passing implies this one will, it's true, but not vice-versa. My thinking here is that if the equality test fails but this test passes, it narrows down the problem.
packages/utils/test/string.test.ts
Outdated
}); | ||
|
||
test('conversion functions are inverses', () => { | ||
expect(base64ToUnicode(unicodeToBase64(unicodeString))).toEqual(unicodeString); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is logically implied from the assertion above it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose that's true. I can remove it. (I'm not going to push the change until after the ember test problem is fixed, though, because I'm just going to have to rebase on top of that fix and push again at that point.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spotty review from mobile on the go. Sorry sorry
Afraid this is such a large commit touching 50+ files ... Maybe could have some of those trivial changes touching many test files be a separate PR...
try { | ||
return unicodeToBase64(JSON.stringify(dropUndefinedKeys(data))).replace(/={1,2}$/, ''); | ||
} catch (err) { | ||
throw new SentryError(`[Tracing] Error computing tracestate value from data: ${err}\nData: ${data}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm this could lead to a spammy stream of errors sent to Sentry if clients are sending bad data. It would be a safer approach here to ignore invalid input, might log the error to the console.
Users can't really fix this error once they see it in Sentry. Either our SDKs have a bug or a bad client is sending data and SDK users can't really fix it on their own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it'll get through to users' issue streams. Because it's a SentryError
, it'll just get thrown rather than captured - see
sentry-javascript/packages/core/src/baseclient.ts
Lines 542 to 559 in e46ff3e
this._sendEvent(processedEvent); | |
return processedEvent; | |
}) | |
.then(null, reason => { | |
if (reason instanceof SentryError) { | |
throw reason; | |
} | |
this.captureException(reason, { | |
data: { | |
__sentry__: true, | |
}, | |
originalException: reason as Error, | |
}); | |
throw new SentryError( | |
`Event processing pipeline threw an error, original event will not be sent. Details have been sent as a new event.\nReason: ${reason}`, | |
); | |
}); |
if (!('environment' in event)) { | ||
event.environment = 'environment' in options ? environment : 'production'; | ||
if (event.environment === undefined && environment !== undefined) { | ||
event.environment = environment; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this related to tracestate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Environment is part of the data that goes into tracestate, so it needs to be set in time for that to happen. If the user provides an environment, we're already good, but if we need to use the default, at the moment that's not getting added until we're sending the event. This moves it earlier so that it's available when we compute the tracestate
value.
See #3242.
@@ -571,7 +547,6 @@ describe('BaseClient', () => { | |||
expect(TestBackend.instance!.event!).toEqual({ | |||
breadcrumbs: [normalizedBreadcrumb, normalizedBreadcrumb, normalizedBreadcrumb], | |||
contexts: normalizedObject, | |||
environment: 'production', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test changes seen unrelated to tracestate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment above re: setting default environment earlier.
It was separate PRs - all of the ones listed in the PR description - all of which have already been reviewed. The only reason this is a new PR and not just a straight-up rebase of the branch is because it was getting too messy. So if there are glaring problems I'm happy to fix them, but anything other than that should probably be handled in a separate PR, since this is meant to be equivalent to having done the rebase directly. |
3bf477f
to
dd76840
Compare
Given that this has all been reviewed as part of the old PRs, and that it's getting merged into a feature branch rather than |
6b1fbfa
to
dd76840
Compare
This is the result of rebasing the feature branch for the initial implementation of `tracestate` header handling (which had grown very stale) on top of current `master`. That branch is going to get deleted, so for posterity, it included the following PRs (oldest -> newest): feat(tracing): Add dynamic sampling correlation context data to envelope header (#3062) chore(utils): Split browser/node compatibility utils into separate module (#3123) ref(tracing): Prework for initial `tracestate` implementation (#3242) feat(tracing): Add `tracestate` header to outgoing requests (#3092) ref(tracing): Rework tracestate internals to allow for third-party data (#3266) feat(tracing): Handle incoming tracestate data, allow for third-party data (#3275) chore(tracing): Various small fixes to first `tracestate` implementation (#3291) fix(tracing): Use `Request.headers.append` correctly (#3311) feat(tracing): Add user data to tracestate header (#3343) chore(various): Small fixes (#3368) fix(build): Prevent Node's `Buffer` module from being included in browser bundles (#3372) fix(tracing): Remove undefined tracestate data rather than setting it to `null` (#3373) More detail in the PR description.
This is the result of rebasing the feature branch for the initial implementation of `tracestate` header handling (which had grown very stale) on top of current `master`. That branch is going to get deleted, so for posterity, it included the following PRs (oldest -> newest): feat(tracing): Add dynamic sampling correlation context data to envelope header (#3062) chore(utils): Split browser/node compatibility utils into separate module (#3123) ref(tracing): Prework for initial `tracestate` implementation (#3242) feat(tracing): Add `tracestate` header to outgoing requests (#3092) ref(tracing): Rework tracestate internals to allow for third-party data (#3266) feat(tracing): Handle incoming tracestate data, allow for third-party data (#3275) chore(tracing): Various small fixes to first `tracestate` implementation (#3291) fix(tracing): Use `Request.headers.append` correctly (#3311) feat(tracing): Add user data to tracestate header (#3343) chore(various): Small fixes (#3368) fix(build): Prevent Node's `Buffer` module from being included in browser bundles (#3372) fix(tracing): Remove undefined tracestate data rather than setting it to `null` (#3373) More detail in the PR description.
This is the result of rebasing the feature branch for the initial implementation of `tracestate` header handling (which had grown very stale) on top of current `master`. That branch is going to get deleted, so for posterity, it included the following PRs (oldest -> newest): feat(tracing): Add dynamic sampling correlation context data to envelope header (#3062) chore(utils): Split browser/node compatibility utils into separate module (#3123) ref(tracing): Prework for initial `tracestate` implementation (#3242) feat(tracing): Add `tracestate` header to outgoing requests (#3092) ref(tracing): Rework tracestate internals to allow for third-party data (#3266) feat(tracing): Handle incoming tracestate data, allow for third-party data (#3275) chore(tracing): Various small fixes to first `tracestate` implementation (#3291) fix(tracing): Use `Request.headers.append` correctly (#3311) feat(tracing): Add user data to tracestate header (#3343) chore(various): Small fixes (#3368) fix(build): Prevent Node's `Buffer` module from being included in browser bundles (#3372) fix(tracing): Remove undefined tracestate data rather than setting it to `null` (#3373) More detail in the PR description.
This is the result of rebasing the feature branch for the initial implementation of
tracestate
header handling (which had grown very stale) on top of currentmaster
. That branch is going to get deleted, so for posterity, it included the following PRs (oldest -> newest):feat(tracing): Add dynamic sampling correlation context data to envelope header (#3062)
chore(utils): Split browser/node compatibility utils into separate module (#3123)
ref(tracing): Prework for initial
tracestate
implementation (#3242)feat(tracing): Add
tracestate
header to outgoing requests (#3092)ref(tracing): Rework tracestate internals to allow for third-party data (#3266)
feat(tracing): Handle incoming tracestate data, allow for third-party data (#3275)
chore(tracing): Various small fixes to first
tracestate
implementation (#3291)fix(tracing): Use
Request.headers.append
correctly (#3311)feat(tracing): Add user data to tracestate header (#3343)
chore(various): Small fixes (#3368)
fix(build): Prevent Node's
Buffer
module from being included in browser bundles (#3372)fix(tracing): Remove undefined tracestate data rather than setting it to
null
(#3373)(This isn't a literal rebasing - the commits in this PR are different from those above - because in each original commit there were so many merge conflicts, in so many parts of so many different files, that it seemed easier to apply the final state of that branch to current
master
and back-engineer a commit history from there, so that I only had to detangle each section of code once.)Of all the
TODO
s included in those PR descriptions, the ones that remain relevant are:id
andsegment
. For now, the id is sent un-hashed (until we can figure out exactly how we want to handle hashing in a way which is repeatable across platforms).In the meantime, one new one has cropped up:
tracestate
data. In doing this, we'll need to note all of the places where a transaction's name changes partway through (or at the end of) its lifecycle, as this could mean that the value in the propagatedtracestate
(depending on when it's computed) might not match the final value on the transaction event itself. (Most often, these midstream name changes are the result of replacing a literal URL (/dogs/maisey
) with a parameterized one (/dogs/:name
), which can't be done until the framework has finished routing the request.) It's an open question what to do with such a mismatch, but at minimum we should know when it might happen.The only other notable thing about the branch is that there's a fairly comprehensive description of
tracestate
lazy computation (which might be useful for thedevelop
docs) included in the description for #3343.