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

feat(opentelemetry): Ensure DSC & attributes are correctly set #10806

Merged
merged 11 commits into from
Feb 27, 2024

Conversation

mydea
Copy link
Member

@mydea mydea commented Feb 26, 2024

This PR fixes a few things about the OTEL handling of our SDK.

  1. Ensure that attributes are actually correctly put on the trace data - we used to remove e.g. sentry.sample_rate which we don't do in "main" SDK. Question: Should we remove the otel.attributes context data then? As this is kind of redundant at this point with the data on the trace?
  2. Ensure we put the transaction tag correctly on the transaction, to align with "main" SDK.
  3. Ensure we store the incoming DSC as traceState, so we can pick this up. This can include e.g. transaction name and stuff like this to persist.

Copy link
Contributor

github-actions bot commented Feb 26, 2024

size-limit report 📦

Path Size
@sentry/browser (incl. Tracing, Replay, Feedback) - Webpack (gzipped) 77.29 KB (0%)
@sentry/browser (incl. Tracing, Replay) - Webpack (gzipped) 68.55 KB (0%)
@sentry/browser (incl. Tracing, Replay with Canvas) - Webpack (gzipped) 72.46 KB (0%)
@sentry/browser (incl. Tracing, Replay) - Webpack with treeshaking flags (gzipped) 62.05 KB (0%)
@sentry/browser (incl. Tracing) - Webpack (gzipped) 32.73 KB (0%)
@sentry/browser (incl. browserTracingIntegration) - Webpack (gzipped) 32.73 KB (0%)
@sentry/browser (incl. Feedback) - Webpack (gzipped) 30.91 KB (0%)
@sentry/browser (incl. sendFeedback) - Webpack (gzipped) 30.91 KB (0%)
@sentry/browser - Webpack (gzipped) 22.19 KB (0%)
@sentry/browser (incl. Tracing, Replay, Feedback) - ES6 CDN Bundle (gzipped) 75.69 KB (0%)
@sentry/browser (incl. Tracing, Replay) - ES6 CDN Bundle (gzipped) 67.46 KB (0%)
@sentry/browser (incl. Tracing) - ES6 CDN Bundle (gzipped) 33.24 KB (0%)
@sentry/browser - ES6 CDN Bundle (gzipped) 24.74 KB (0%)
@sentry/browser (incl. Tracing, Replay) - ES6 CDN Bundle (minified & uncompressed) 211.04 KB (0%)
@sentry/browser (incl. Tracing) - ES6 CDN Bundle (minified & uncompressed) 99.76 KB (0%)
@sentry/browser - ES6 CDN Bundle (minified & uncompressed) 73.96 KB (0%)
@sentry/browser (incl. Tracing) - ES5 CDN Bundle (gzipped) 36.29 KB (0%)
@sentry/react (incl. Tracing, Replay) - Webpack (gzipped) 68.83 KB (0%)
@sentry/react - Webpack (gzipped) 22.22 KB (0%)
@sentry/nextjs Client (incl. Tracing, Replay) - Webpack (gzipped) 85.24 KB (0%)
@sentry/nextjs Client - Webpack (gzipped) 49.62 KB (0%)
@sentry-internal/feedback - Webpack (gzipped) 17.14 KB (0%)

Copy link
Member

@Lms24 Lms24 left a comment

Choose a reason for hiding this comment

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

LGTM!

Should we remove the otel.attributes context data then?

What field is this exactly on the event? I don't think we should remove stuff from event.contexts.trace.data (which IIUC span attributes end up in) because IIRC either ingest or the product later need these fields.

@mydea
Copy link
Member Author

mydea commented Feb 27, 2024

LGTM!

Should we remove the otel.attributes context data then?

What field is this exactly on the event? I don't think we should remove stuff from event.contexts.trace.data (which IIUC span attributes end up in) because IIRC either ingest or the product later need these fields.

What I mean is that we send the "root span" attributes in contexts.trace.data, but we also send all otel span attributes in contexts.otel.attributes - which now is basically the same list of attributes, twice 🤔

Copy link
Member

@lforst lforst left a comment

Choose a reason for hiding this comment

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

I have a feeling that we are missing the inverse logic in inject. More concretely we need to take the dynamic sampling context of the current span when inject is called, e.g. by calling getDynamicSamplingContextFromSpan([current span]) on the current span. I think I might have missed this previously.

return event;
}

const spanContext = span.spanContext();

// If event has already set `trace` context, use that one.
event.contexts = {
trace: {
trace: dropUndefinedKeys({
Copy link
Member

Choose a reason for hiding this comment

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

Why do we have to add dropUndefinedKeys here?

Copy link
Member Author

Choose a reason for hiding this comment

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

I figured it's nicer to not send an undefined parent_span_id (this was one debugging step when I was fixing tests etc), but we can also leave it!

const rootSpan = getRootSpan(span);
const transactionName = spanHasName(rootSpan) ? rootSpan.name : undefined;
if (transactionName) {
event.tags = { transaction: transactionName, ...event.tags };
Copy link
Member

Choose a reason for hiding this comment

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

Is transaction really a tag? I thought the transaction for an error was stored in the top level transaction field.

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 store both of these right now - we can revisit later if this is (still?) needed, but I figured to maintain parity for now this makes sense!

@@ -159,13 +171,13 @@ function createTransactionForOtelSpan(span: ReadableSpan): Transaction {
status: mapStatus(span),
startTimestamp: convertOtelTimeToSeconds(span.startTime),
metadata: {
sampleRate: span.attributes[SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE] as number | undefined,
...dropUndefinedKeys({
Copy link
Member

Choose a reason for hiding this comment

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

Same q: Why dropUndefinedKeys here?

Copy link
Member Author

Choose a reason for hiding this comment

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

here I think it is important, because dynamicSamplingContext may be undefined in which case we don't want to set it, because later in the pipeline if you have e.g. this:

metadata: {
  dynamicSamplingContext: xx,
  ...event.metadata
}

this would overwrite xx even if it is undefined, I think?

Copy link
Member

Choose a reason for hiding this comment

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

right... makes sense! Thank you!

@@ -180,7 +192,14 @@ function createTransactionForOtelSpan(span: ReadableSpan): Transaction {
});

if (capturedSpanScopes) {
setCapturedScopesOnTransaction(transaction, capturedSpanScopes.scope, capturedSpanScopes.isolationScope);
// Ensure the `transaction` tag is correctly set on the transaction event
Copy link
Member

Choose a reason for hiding this comment

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

Same q: Is the transaction value really a tag? It shows up in the interface as tag but I think it is top level on the event, eg: https://us.sentry.io/api/0/projects/sentry/sentry/events/9f6a861ccacf43868a4d7d6d63b9d922/json/

packages/opentelemetry/src/utils/dynamicSamplingContext.ts Outdated Show resolved Hide resolved
@mydea
Copy link
Member Author

mydea commented Feb 27, 2024

OK, I also updated the propagator to look at the span trace state first, and only then fall back to propagation context! I also added tests to cover this, and also to ensure trace state is correctly inherited & applied for spans.

@mydea mydea merged commit 240fd8a into develop Feb 27, 2024
105 checks passed
@mydea mydea deleted the fn/otel-dsc-attributes branch February 27, 2024 16:38
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.

None yet

3 participants