Skip to content

feat(core): Add ignoreSpans option #17078

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

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open

feat(core): Add ignoreSpans option #17078

wants to merge 3 commits into from

Conversation

mydea
Copy link
Member

@mydea mydea commented Jul 18, 2025

This adds a new ignoreSpans option to all SDKs. This can be used as follows:

Sentry.init({
  ignoreSpans: ['partial match', /regex/, { name: 'span name', op: 'http.client' }]
});

this will drop spans before they are sent. Eventual child spans in the same envelope will be re-parented, if possible.

Closes #16820

@mydea mydea self-assigned this Jul 18, 2025
Copy link
Contributor

github-actions bot commented Jul 18, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 23.97 kB added added
@sentry/browser - with treeshaking flags 22.55 kB added added
@sentry/browser (incl. Tracing) 39.87 kB added added
@sentry/browser (incl. Tracing, Replay) 78.02 kB added added
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 67.86 kB added added
@sentry/browser (incl. Tracing, Replay with Canvas) 82.72 kB added added
@sentry/browser (incl. Tracing, Replay, Feedback) 94.82 kB added added
@sentry/browser (incl. Feedback) 40.66 kB added added
@sentry/browser (incl. sendFeedback) 28.65 kB added added
@sentry/browser (incl. FeedbackAsync) 33.54 kB added added
@sentry/react 25.7 kB added added
@sentry/react (incl. Tracing) 41.81 kB added added
@sentry/vue 28.43 kB added added
@sentry/vue (incl. Tracing) 41.66 kB added added
@sentry/svelte 23.99 kB added added
CDN Bundle 25.38 kB added added
CDN Bundle (incl. Tracing) 39.66 kB added added
CDN Bundle (incl. Tracing, Replay) 75.67 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) 81.12 kB added added
CDN Bundle - uncompressed 74.09 kB added added
CDN Bundle (incl. Tracing) - uncompressed 117.64 kB added added
CDN Bundle (incl. Tracing, Replay) - uncompressed 231.78 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 244.6 kB added added
@sentry/nextjs (client) 43.87 kB added added
@sentry/sveltekit (client) 40.31 kB added added
@sentry/node-core 47.44 kB added added
@sentry/node 144.05 kB added added
@sentry/node - without tracing 91.5 kB added added
@sentry/aws-serverless 102.94 kB added added

@mydea mydea requested review from bcoe, Lms24 and s1gr1d July 18, 2025 10:55
@mydea mydea marked this pull request as ready for review July 18, 2025 10:55
cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Bug: Span Ignoring Fails for Operations Without Descriptions

The shouldIgnoreSpan function returns false early if span.description is falsy. This prevents ignoreSpans patterns that match solely on the op field (e.g., { op: 'http.client' }) from being applied. Consequently, spans without a description but with a matching op are not ignored, as they never reach the logic designed for op-only pattern matching.

packages/core/src/utils/should-ignore-span.ts#L15-L18

if (!span.description) {
return false;
}

Fix in CursorFix in Web


Was this report helpful? Give feedback by reacting with 👍 or 👎

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.

Nice! Had some suggestions for types and performance

Comment on lines +16 to +18
if (!span.description) {
return false;
}
Copy link
Member

Choose a reason for hiding this comment

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

l: I can't think of an actual example right now but theoretically, shouldn't we still match on the op of a span without a description?

// update event with processed root span values
processedEvent = merge(event, convertSpanJsonToTransactionEvent(processedRootSpanJson));
// Avoid processing if we don't have to
if (beforeSendSpan || ignoreSpans) {
Copy link
Member

Choose a reason for hiding this comment

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

l: This should save a bit of performance overhead in case the passed array is empty

Suggested change
if (beforeSendSpan || ignoreSpans) {
if (beforeSendSpan || ignoreSpans && ignoreSpans.length) {

Comment on lines +21 to +31
const simplePatterns = ignoreSpans.filter(isStringOrRegExp);
if (simplePatterns.length && stringMatchesSomePattern(span.description, simplePatterns)) {
return true;
}

// Then we check the more complex patterns, where both parts must match
for (const pattern of ignoreSpans) {
// Have already checked for simple patterns, so we can skip these
if (isStringOrRegExp(pattern) || (!pattern.name && !pattern.op)) {
continue;
}
Copy link
Member

Choose a reason for hiding this comment

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

l: I think performance-wise, it makes more sense to handle everything in one for loop here, no? If users didn't pass simple patterns or none of them matched, we'd iterate twice over the ignoreSpans array. Also avoids calling isStringOrRegExp twice in this case.
(not the end of the world but it scales with the number of spans...)

@@ -10,6 +10,11 @@ import type { StackLineParser, StackParser } from './stacktrace';
import type { TracePropagationTargets } from './tracing';
import type { BaseTransportOptions, Transport } from './transport';

interface IgnoreSpanFilter {
Copy link
Member

Choose a reason for hiding this comment

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

m: I think we can type this a bit smarter, right? Currently, this allows users to pass in an empty object but we could type it in a way so that at least one prop is required

Suggested change
interface IgnoreSpanFilter {
type IgnoreSpanFilter = {
name: string | RegExp;
op?: string | RegExp;
} | {
name?: string | RegExp;
op: string | RegExp;
}

we should probably still check that this is also enforced when we apply the option (which we do already)

Comment on lines +33 to +38
const nameMatches = pattern.name ? isMatchingPattern(span.description, pattern.name) : true;
const opMatches = pattern.op ? span.op && isMatchingPattern(span.op, pattern.op) : true;

if (nameMatches && opMatches) {
return true;
}
Copy link
Member

Choose a reason for hiding this comment

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

this is pretty clever, took me a minute to understand :D
maybe we can add a comment that it's only safe to return true here because we already bailed earlier if both op and name were undefined.

Suggested change
const nameMatches = pattern.name ? isMatchingPattern(span.description, pattern.name) : true;
const opMatches = pattern.op ? span.op && isMatchingPattern(span.op, pattern.op) : true;
if (nameMatches && opMatches) {
return true;
}
// because of the check above, only one one of them can be undefined, so falling
// back to `true` (in combination with the check below) is safe here
const nameMatches = pattern.name ? isMatchingPattern(span.description, pattern.name) : true;
const opMatches = pattern.op ? span.op && isMatchingPattern(span.op, pattern.op) : true;
if (nameMatches && opMatches) {
return true;
}

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.

Add ignoreSpans option
2 participants