Skip to content

feat(envelopes): Add SDK metadata to envelope header #3170

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

Closed
wants to merge 10 commits into from

Conversation

lobsterkatie
Copy link
Member

@lobsterkatie lobsterkatie commented Jan 12, 2021

UPDATE: Closed in favor of #3177.

This adds SDK data to envelope headers, per the spec here.

SDK data varies by package, but envelope headers are created in @sentry/core, which has no idea what package is calling it. Therefore, in this PR each SDK adds its own metadata to globalObj.__SENTRY__ so that @sentry/core can retrieve it when necessary. (This also means that event processors have access to it, but taking advantage of that fact will happen in a separate PR.)

@lobsterkatie lobsterkatie force-pushed the kmclb-sdk-info-in-envelope-header branch from 231931c to 8eb52a3 Compare January 12, 2021 17:07
@github-actions
Copy link
Contributor

github-actions bot commented Jan 12, 2021

size-limit report

Path Size
@sentry/browser - CDN Bundle (gzipped) 20.16 KB (+0.84% 🔺)
@sentry/browser - Webpack 20.88 KB (+0.23% 🔺)
@sentry/react - Webpack 20.88 KB (+0.23% 🔺)
@sentry/browser + @sentry/tracing - CDN Bundle (gzipped) 27.31 KB (+0.57% 🔺)

Copy link
Contributor

@rhcarvalho rhcarvalho left a comment

Choose a reason for hiding this comment

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

Therefore, in this PR each SDK adds its own metadata to globalObj.__SENTRY__ so that @sentry/core can retrieve it when necessary.

While this might be an expedient solution, I'd really like us to invest on more maintainable design. Globals bring all sorts of problems (affects compiler logic eventually influencing bundle size, limits concurrency, complicates tests, cannot have multiple SDKs loaded at once, ...)

For events there is a clear path forward: the event already has SDK info. For sessions it is not part of the session JSON structure, but we could add it to a session in-memory representation, unless there are good reasons not to do it.

Alternatively, we can configure the transport on init time to know what SDK info it should use to report events/sessions -- the SDK info shall not change in runtime/per event||session, right?

Comment on lines +63 to +82
"jest": {
"collectCoverage": true,
"transform": {
"^.+\\.ts$": "ts-jest"
},
"moduleFileExtensions": [
"js",
"ts"
],
"testEnvironment": "jsdom",
"testMatch": [
"**/*.test.ts"
],
"globals": {
"ts-jest": {
"tsConfig": "./tsconfig.json",
"diagnostics": false
}
}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks unrelated to the subject. If that's the case, can we move it off to a separate PR for clarity?

@@ -39,9 +42,12 @@ export function eventToSentryRequest(event: Event, api: API): SentryRequest {
// deserialization. Instead, we only implement a minimal subset of the spec to
// serialize events inline here.
if (useEnvelope) {
const { name, version } = getGlobalObject().__SENTRY__?.sdkInfo || {};
Copy link
Contributor

Choose a reason for hiding this comment

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

Does Relay actually accept sending an sdk envelope header with an empty object? If it doesn't, the correct behavior would be to omit this header entry if we don't have SDK info.

const envelopeHeaders = JSON.stringify({
event_id: event.event_id,
sent_at: new Date().toISOString(),
sdk: { name, version },
Copy link
Contributor

Choose a reason for hiding this comment

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

For events, we could take this info off event.sdk, so no need for using the global namespace. Note how eventToSentryRequest was a pure function before this change. The returned request could be computed solely based on the inputs.

Using event.sdk also guarantees by construction that both values match. For multi-language SDKs, like react-native, is there a case for reporting different SDKs in the event vs envelope? 🤔


import { API } from './api';

/** Creates a SentryRequest from an event. */
export function sessionToSentryRequest(session: Session, api: API): SentryRequest {
const { name, version } = getGlobalObject().__SENTRY__?.sdkInfo || {};
Copy link
Contributor

Choose a reason for hiding this comment

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

It is better design to pass dependencies explicitly instead of using the global namespace. What Kamil keeps saying about pure functions and avoiding side-effects ;)

Functions like sessionToSentryRequest are easier to test and to reason about if their output depends solely on the inputs, and never on other external state like global variables.

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.

3 participants