Skip to content

Commit

Permalink
feat(solidstart): Filter out low quality transactions for build assets (
Browse files Browse the repository at this point in the history
  • Loading branch information
andreiborza authored Aug 5, 2024
1 parent e6642a7 commit bedc385
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/solidstart/src/server/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { applySdkMetadata } from '@sentry/core';
import type { NodeClient, NodeOptions } from '@sentry/node';
import { init as initNodeSdk } from '@sentry/node';
import { filterLowQualityTransactions } from './utils';

/**
* Initializes the server side of the Solid Start SDK
Expand All @@ -11,6 +12,7 @@ export function init(options: NodeOptions): NodeClient | undefined {
};

applySdkMetadata(opts, 'solidstart', ['solidstart', 'node']);
filterLowQualityTransactions(opts);

return initNodeSdk(opts);
}
26 changes: 25 additions & 1 deletion packages/solidstart/src/server/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { flush } from '@sentry/node';
import { flush, getGlobalScope } from '@sentry/node';
import type { EventProcessor, Options } from '@sentry/types';
import { logger } from '@sentry/utils';
import { DEBUG_BUILD } from '../common/debug-build';

Expand Down Expand Up @@ -31,3 +32,26 @@ export function isRedirect(error: unknown): boolean {
const hasValidStatus = error.status >= 300 && error.status <= 308;
return hasValidLocation && hasValidStatus;
}

/**
* Adds an event processor to filter out low quality transactions,
* e.g. to filter out transactions for build assets
*/
export function filterLowQualityTransactions(options: Options): void {
getGlobalScope().addEventProcessor(
Object.assign(
(event => {
if (event.type !== 'transaction') {
return event;
}
// Filter out transactions for build assets
if (event.transaction?.match(/^GET \/_build\//)) {
options.debug && logger.log('SolidStartLowQualityTransactionsFilter filtered transaction', event.transaction);
return null;
}
return event;
}) satisfies EventProcessor,
{ id: 'SolidStartLowQualityTransactionsFilter' },
),
);
}
38 changes: 36 additions & 2 deletions packages/solidstart/test/server/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { NodeClient } from '@sentry/node';
import { SDK_VERSION } from '@sentry/node';
import * as SentryNode from '@sentry/node';

import { vi } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { init as solidStartInit } from '../../src/server';

const browserInit = vi.spyOn(SentryNode, 'init');
Expand Down Expand Up @@ -33,4 +33,38 @@ describe('Initialize Solid Start SDK', () => {
expect(browserInit).toHaveBeenCalledTimes(1);
expect(browserInit).toHaveBeenLastCalledWith(expect.objectContaining(expectedMetadata));
});

it('filters out low quality transactions', async () => {
const beforeSendEvent = vi.fn(event => event);
const client = solidStartInit({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
}) as NodeClient;
client.on('beforeSendEvent', beforeSendEvent);

client.captureEvent({ type: 'transaction', transaction: 'GET /' });
client.captureEvent({ type: 'transaction', transaction: 'GET /_build/some_asset.js' });
client.captureEvent({ type: 'transaction', transaction: 'POST /_server' });

await client!.flush();

expect(beforeSendEvent).toHaveBeenCalledTimes(2);
expect(beforeSendEvent).toHaveBeenCalledWith(
expect.objectContaining({
transaction: 'GET /',
}),
expect.any(Object),
);
expect(beforeSendEvent).not.toHaveBeenCalledWith(
expect.objectContaining({
transaction: 'GET /_build/some_asset.js',
}),
expect.any(Object),
);
expect(beforeSendEvent).toHaveBeenCalledWith(
expect.objectContaining({
transaction: 'POST /_server',
}),
expect.any(Object),
);
});
});
2 changes: 1 addition & 1 deletion packages/types/src/eventprocessor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Event, EventHint } from './event';

/**
* Event processors are used to change the event before it will be send.
* Event processors are used to change the event before it will be sent.
* We strongly advise to make this function sync.
* Returning a PromiseLike<Event | null> will work just fine, but better be sure that you know what you are doing.
* Event processing will be deferred until your Promise is resolved.
Expand Down

0 comments on commit bedc385

Please sign in to comment.