Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Add option to sample linked traces consistently · Issue #15754 · getsentry/sentry-javascript · GitHub
Skip to content

Add option to sample linked traces consistently #15754

Description

@Lms24

We should provide a way for users to sample consistently positively or negatively based on the previous/initial trace (i.e. the one we link since #14992). Concretely, we propose to add an option to browserTracingIntegration:

Sentry.init({integrations: [browserTracingIntegration({linkPreviousTrace: 'in-memory',// other values 'session-storage' | 'off'sampleLikePreviousTrace: true,// does nothing if linkPreviousTrace === 'off'})]})

This option is opt-in, meaning by default, the SDK continues to sample independently between traces.

Specifically, if sampleLikePreviousTrace is true

  • force a positive sampling decision if previous trace was sampled positively
    • ensure that sample rand and rate from initial trace is applied and propagated in new trace
  • force negative sampling decision if previous trace was sampled negatively
  • fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) if no previous trace available (e.g. because first trace in chain or linkPreviousTrace === 'off')
  • injected meta tags on pageload have precedence over previous trace sampling decision (if session-storage is opted into)

Otherwise, fall back to fall back to user-defined sampling mechanism (tracesSampleRate or tracesSampler) => independent sampling.

As for implementation: We probably can reuse the beforeSampling client hook to keep the logic in browserTracingIntegration. But we need to make sure that the hook emits in sampleSpan (or prior to calling it) within the Core SDK. Also we need to update or set the propagation context accordingly.

In other words, the only way how consistent sampling across traces can work is by pretending it is continuing a sampling decision within a distributed trace. Which is a fundamental limitation of the tracing and metrics model we're building at Sentry. This really shows that tracesSampler still permits a lot of possibilities for users to influence extrapolation in unexpected ways.

Naming

Naming is hard and I don't have a great name yet for this option. Some suggestions:


The initial proposal was reworked b/c it would have significantly skewed span metric extrapolation. I'm leaving this here for some context as to what we could have had.

Initial Proposal (for context)

Description

We should provide a way for users to make a sampling decision for a trace based on the sampling decision of the previous trace (i.e. the one we link since #14992). Concretely, we propose to add an option to tracesSampler:

Sentry.init({dsn: '...',tracesSampler(({previousTraceSampled})=>{if(previousTraceSampled){return1.0;// could also just increase the rate, e.g. to 0.5}elseif(previousTraceSampled===false){return0;}return0.05;})})

where previousTraceSampled is typed as boolean | undefined. The semantics for all values:

  • true - previous trace was positively sampled and sent to Sentry (this makes no guarantees that this trace in fact was stored; it can still be dropped by Relay)
  • false - previous trace was negatively sampled and not Sent to Sentry
  • undefined - multiple implications
    • the current trace is the first one
    • previous trace collection is disabled by users
    • previous trace collection is not available (e.g. server SDK)

This allows users to ensure that a trace chain is longer or in general more complete.

Important notes:

  • By default the SDK will not continue a positive sampling decision based on the previous trace. This must be a concious user decision to opt into.
  • The potential quota increase must be mentioned in JSDoc and docs

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions