Skip to content

feat(core): Add ignoreTransactions option #7594

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

Merged
merged 1 commit into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/core/src/integrations/inboundfilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface InboundFiltersOptions {
allowUrls: Array<string | RegExp>;
denyUrls: Array<string | RegExp>;
ignoreErrors: Array<string | RegExp>;
ignoreTransactions: Array<string | RegExp>;
ignoreInternal: boolean;
}

Expand Down Expand Up @@ -63,6 +64,7 @@ export function _mergeOptions(
...(clientOptions.ignoreErrors || []),
...DEFAULT_IGNORE_ERRORS,
],
ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],
ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,
};
}
Expand All @@ -81,6 +83,13 @@ export function _shouldDropEvent(event: Event, options: Partial<InboundFiltersOp
);
return true;
}
if (_isIgnoredTransaction(event, options.ignoreTransactions)) {
__DEBUG_BUILD__ &&
logger.warn(
`Event dropped due to being matched by \`ignoreTransactions\` option.\nEvent: ${getEventDescription(event)}`,
);
return true;
}
if (_isDeniedUrl(event, options.denyUrls)) {
__DEBUG_BUILD__ &&
logger.warn(
Expand Down Expand Up @@ -111,6 +120,15 @@ function _isIgnoredError(event: Event, ignoreErrors?: Array<string | RegExp>): b
return _getPossibleEventMessages(event).some(message => stringMatchesSomePattern(message, ignoreErrors));
}

function _isIgnoredTransaction(event: Event, ignoreTransactions?: Array<string | RegExp>): boolean {
if (event.type !== 'transaction' || !ignoreTransactions || !ignoreTransactions.length) {
return false;
}

const name = event.transaction;
return name ? stringMatchesSomePattern(name, ignoreTransactions) : false;
}

function _isDeniedUrl(event: Event, denyUrls?: Array<string | RegExp>): boolean {
// TODO: Use Glob instead?
if (!denyUrls || !denyUrls.length) {
Expand Down
63 changes: 63 additions & 0 deletions packages/core/test/lib/integrations/inboundfilters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ const MALFORMED_EVENT: Event = {

const TRANSACTION_EVENT: Event = {
message: 'transaction message',
transaction: 'transaction name',
type: 'transaction',
};

const TRANSACTION_EVENT_2: Event = {
transaction: 'transaction name 2',
type: 'transaction',
};

const TRANSACTION_EVENT_3: Event = {
transaction: 'other name',
type: 'transaction',
};

Expand Down Expand Up @@ -284,6 +295,58 @@ describe('InboundFilters', () => {
});
});

describe('ignoreTransactions', () => {
it('string filter with partial match', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: ['name'],
});
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(null);
});

it('ignores error event for filtering', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: ['capture'],
});
expect(eventProcessor(MESSAGE_EVENT, {})).toBe(MESSAGE_EVENT);
});

it('string filter with exact match', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: ['transaction name'],
});
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(null);
});

it('regexp filter with partial match', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: [/name/],
});
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(null);
});

it('regexp filter with exact match', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: [/^transaction name$/],
});
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(null);
expect(eventProcessor(TRANSACTION_EVENT_2, {})).toBe(TRANSACTION_EVENT_2);
});

it('can use multiple filters', () => {
const eventProcessor = createInboundFiltersEventProcessor({
ignoreTransactions: ['transaction name 2', /transaction/],
});
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(null);
expect(eventProcessor(TRANSACTION_EVENT_2, {})).toBe(null);
expect(eventProcessor(TRANSACTION_EVENT_3, {})).toBe(TRANSACTION_EVENT_3);
});

it('uses default filters', () => {
const eventProcessor = createInboundFiltersEventProcessor();
expect(eventProcessor(TRANSACTION_EVENT, {})).toBe(TRANSACTION_EVENT);
});
});

describe('denyUrls/allowUrls', () => {
it('should filter captured message based on its stack trace using string filter', () => {
const eventProcessorDeny = createInboundFiltersEventProcessor({
Expand Down
6 changes: 6 additions & 0 deletions packages/types/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,12 @@ export interface ClientOptions<TO extends BaseTransportOptions = BaseTransportOp
*/
ignoreErrors?: Array<string | RegExp>;

/**
* A pattern for transaction names which should not be sent to Sentry.
* By default, all transactions will be sent.
*/
ignoreTransactions?: Array<string | RegExp>;

/**
* A URL to an envelope tunnel endpoint. An envelope tunnel is an HTTP endpoint
* that accepts Sentry envelopes for forwarding. This can be used to force data
Expand Down