Skip to content

feat: Add strict trace continuation support#5136

Draft
giortzisg wants to merge 12 commits intomainfrom
feat/strict-trace-continuation
Draft

feat: Add strict trace continuation support#5136
giortzisg wants to merge 12 commits intomainfrom
feat/strict-trace-continuation

Conversation

@giortzisg
Copy link

Summary

  • Extract org ID from DSN host (e.g., o123.ingest.sentry.io"123")
  • Add strictTraceContinuation (boolean, default false) and orgId (String) options to SentryOptions
  • Propagate sentry-org_id in baggage / Dynamic Sampling Context
  • Validate incoming traces per the decision matrix (mismatched org → new trace; strict mode rejects missing org)

Decision Matrix

Baggage org SDK org strict=false strict=true
1 1 Continue Continue
None 1 Continue New trace
1 None Continue New trace
None None Continue Continue
1 2 New trace New trace

Changes

  • Dsn.java — org ID extraction from host using ^o(\d+)\. regex
  • SentryOptions.javastrictTraceContinuation, orgId, and getEffectiveOrgId()
  • Baggage.javaORG_ID DSCKey, getter/setter, population in setValuesFromTransaction/setValuesFromScope/fromEvent
  • PropagationContext.javashouldContinueTrace() logic in fromHeaders()
  • Scopes.java — pass options to fromHeaders()

Test plan

  • DSN org ID extraction tests (5 cases)
  • PropagationContext decision matrix tests (10 cases)

Closes #5128

🤖 Generated with Claude Code

@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (anr) Profile main thread when ANR and report ANR profiles to Sentry by markushi in #4899
  • Add strict trace continuation support by giortzisg in #5136

Bug Fixes 🐛

  • Remove the dependency on protobuf-lite for tombstones by supervacuus in #5157

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against ea9f456

@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 320.20 ms 367.52 ms 47.33 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
ee747ae 386.94 ms 431.43 ms 44.49 ms
539ca63 313.51 ms 355.43 ms 41.92 ms
22f4345 312.78 ms 347.40 ms 34.62 ms
9fbb112 401.87 ms 515.87 ms 114.00 ms
fcec2f2 357.47 ms 447.32 ms 89.85 ms
d15471f 361.89 ms 378.07 ms 16.18 ms
d15471f 303.49 ms 439.08 ms 135.59 ms
0eaac1e 320.04 ms 369.52 ms 49.48 ms
a5ab36f 320.47 ms 389.77 ms 69.30 ms
27d7cf8 369.82 ms 422.62 ms 52.80 ms

App size

Revision Plain With Sentry Diff
ee747ae 1.58 MiB 2.10 MiB 530.95 KiB
539ca63 1.58 MiB 2.12 MiB 551.41 KiB
22f4345 1.58 MiB 2.29 MiB 719.83 KiB
9fbb112 1.58 MiB 2.11 MiB 539.18 KiB
fcec2f2 1.58 MiB 2.12 MiB 551.50 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
0eaac1e 1.58 MiB 2.19 MiB 619.17 KiB
a5ab36f 1.58 MiB 2.12 MiB 555.26 KiB
27d7cf8 1.58 MiB 2.12 MiB 549.42 KiB

Previous results on branch: feat/strict-trace-continuation

Startup times

Revision Plain With Sentry Diff
79a9407 348.85 ms 428.10 ms 79.25 ms
bbab8da 309.58 ms 363.22 ms 53.64 ms

App size

Revision Plain With Sentry Diff
79a9407 1.58 MiB 2.29 MiB 723.70 KiB
bbab8da 1.58 MiB 2.29 MiB 723.51 KiB

final @NotNull ILogger logger,
final @Nullable String sentryTraceHeaderString,
final @Nullable List<String> baggageHeaderStrings) {
return fromHeaders(logger, sentryTraceHeaderString, baggageHeaderStrings, null);
Copy link
Member

Choose a reason for hiding this comment

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

We could use Sentry.getCurrentScopes().getOptions() here to default to the current options.
The better fix would probably be to replace call sites with passing in options and remove this overload.
Since PropagationContext is marked internal, we're free to change / replace / remove methods.

giortzisg and others added 6 commits March 4, 2026 14:01
Extract org ID from DSN host, add strictTraceContinuation and orgId
options, propagate sentry-org_id in baggage, and validate incoming
traces per the decision matrix.

Closes #5128
Add public API declarations for new org ID and strict trace
continuation methods on Baggage, PropagationContext, and SentryOptions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make Dsn.orgId final, remove unnecessary setter
- Fix test signatures to use List<String> for baggage headers
- Add strictTraceContinuation and orgId to ExternalOptions and merge()
- Add options to ManifestMetadataReader for Android manifest config
- Use Sentry.getCurrentScopes().getOptions() in legacy fromHeaders overload
- Improve CHANGELOG description with details about new options
- Update API surface file for ExternalOptions changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add comment to empty catch block in PropagationContext to satisfy -Werror
- Add setOrgId setter to Dsn class (remove final modifier on orgId field) to
  support the existing test for org ID override

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@giortzisg giortzisg force-pushed the feat/strict-trace-continuation branch from 457e177 to e30064c Compare March 4, 2026 13:14
giortzisg and others added 5 commits March 4, 2026 14:20
…x OTel overload, add option tests, make Dsn.orgId final

- Remove PropagationContext.fromHeaders overload without SentryOptions; all
  callers now pass options (or null) explicitly instead of relying on
  Sentry.getCurrentScopes()
- Add SentryOptions parameter to the OTel-facing fromHeaders(SentryTraceHeader,
  Baggage, SpanId) overload so OpenTelemetry integrations also check orgId
- Make Dsn.orgId final and remove the setter — orgId is only set during
  DSN parsing in the constructor
- Add tests for strictTraceContinuation and orgId options in
  ExternalOptionsTest, SentryOptionsTest, and ManifestMetadataReaderTest
- Improve CHANGELOG entry with customer-facing description
- Update API declarations (apiDump)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@sentry
Copy link

sentry bot commented Mar 9, 2026

Sentry Build Distribution

App Version Configuration
SDK Size 8.34.1 (1) release

Copy link
Member

@adinauer adinauer left a comment

Choose a reason for hiding this comment

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

Please also change SentryAutoConfigurationTest.kt in all 3 spring boot modules.

I assume it's OK to not backfill org ID on a frozen baggage (i.e. incoming baggage without org ID).

}

options.setStrictTraceContinuation(
propertiesProvider.getBooleanProperty("strict-trace-continuation"));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
propertiesProvider.getBooleanProperty("strict-trace-continuation"));
propertiesProvider.getBooleanProperty("enable-strict-trace-continuation"));

Newer options all have the enable prefix

: TransactionContext.fromPropagationContext(
PropagationContext.fromHeaders(
traceData.getSentryTraceHeader(), traceData.getBaggage(), spanId));
traceData.getSentryTraceHeader(), traceData.getBaggage(), spanId, scopes.getOptions()));
Copy link
Member

Choose a reason for hiding this comment

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

We should also update OtelSentrySpanProcessor

return sampleRand == null ? 0.0 : sampleRand;
}

static boolean shouldContinueTrace(
Copy link
Member

Choose a reason for hiding this comment

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

Let's also handle empty/blank strings here. Otherwise we'd silently be breaking traces.

final @NotNull Baggage baggage = Baggage.fromHeader(baggageHeaderStrings, logger);
return fromHeaders(traceHeader, baggage, null);

if (options != null && !shouldContinueTrace(options, baggage)) {
Copy link
Member

Choose a reason for hiding this comment

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

this seems to be duplicated since we're already checking in the other overload that we call here too

final @Nullable SpanId spanId,
final @Nullable SentryOptions options) {
if (options != null && !shouldContinueTrace(options, baggage)) {
return new PropagationContext();
Copy link
Member

Choose a reason for hiding this comment

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

Implementation above logs a debug message, this does not. We should log here to give a hint why traces aren't being continued.

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.

Implement strict trace continuation (org_id validation)

3 participants