Skip to content

Commit f93ccbe

Browse files
authored
fix(nuxt): Avoid sending server resource request transactions (#14497)
Refactor the low quality transaction filter in the Nuxt SDK to filter out all resource requests. Our SDKs should generally not send dedicated transactions for resource requests as they would deplete transaction quota fairly quickly, compared to only tracking page requests.
1 parent 8a4098a commit f93ccbe

File tree

2 files changed

+36
-38
lines changed

2 files changed

+36
-38
lines changed

packages/nuxt/src/server/sdk.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as path from 'node:path';
12
import { applySdkMetadata, flush, getGlobalScope } from '@sentry/core';
23
import { logger, vercelWaitUntil } from '@sentry/core';
34
import {
@@ -33,23 +34,26 @@ export function init(options: SentryNuxtServerOptions): Client | undefined {
3334
}
3435

3536
/**
36-
* Filter out transactions for Nuxt build assets
37-
* This regex matches the default path to the nuxt-generated build assets (`_nuxt`).
37+
* Filter out transactions for resource requests which we don't want to send to Sentry
38+
* for quota reasons.
3839
*
3940
* Only exported for testing
4041
*/
4142
export function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor {
4243
return Object.assign(
4344
(event => {
44-
if (event.type === 'transaction' && event.transaction?.match(/^GET \/_nuxt\//)) {
45-
// todo: the buildAssetDir could be changed in the nuxt config - change this to a more generic solution
45+
if (event.type !== 'transaction' || !event.transaction) {
46+
return event;
47+
}
48+
// We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out
49+
// path.extname will return an empty string for normal page requests
50+
if (path.extname(event.transaction)) {
4651
options.debug &&
4752
DEBUG_BUILD &&
4853
logger.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction);
4954
return null;
50-
} else {
51-
return event;
5255
}
56+
return event;
5357
}) satisfies EventProcessor,
5458
{ id: 'NuxtLowQualityTransactionsFilter' },
5559
);

packages/nuxt/test/server/sdk.test.ts

+26-32
Original file line numberDiff line numberDiff line change
@@ -45,45 +45,39 @@ describe('Nuxt Server SDK', () => {
4545
expect(init({})).not.toBeUndefined();
4646
});
4747

48-
it('filters out low quality transactions', async () => {
48+
describe('low quality transactions filter (%s)', () => {
4949
const beforeSendEvent = vi.fn(event => event);
5050
const client = init({
5151
dsn: 'https://[email protected]/1337',
5252
}) as NodeClient;
5353
client.on('beforeSendEvent', beforeSendEvent);
5454

55-
client.captureEvent({ type: 'transaction', transaction: 'GET /' });
56-
client.captureEvent({ type: 'transaction', transaction: 'GET /_nuxt/some_asset.js' });
57-
// Although this has the name of the build asset directory (_nuxt), it should not be filtered out as it would not match the regex
58-
client.captureEvent({ type: 'transaction', transaction: 'GET _nuxt/some_asset.js' });
59-
client.captureEvent({ type: 'transaction', transaction: 'POST /_server' });
60-
61-
await client!.flush();
55+
it.each([
56+
[
57+
'GET /_nuxt/some_asset.js',
58+
'GET _nuxt/some_asset.js',
59+
'GET /icons/favicon.ico',
60+
'GET /assets/logo.png',
61+
'GET /icons/zones/forest.svg',
62+
],
63+
])('filters out low quality transactions', async transaction => {
64+
client.captureEvent({ type: 'transaction', transaction });
65+
await client!.flush();
66+
expect(beforeSendEvent).not.toHaveBeenCalled();
67+
});
6268

63-
expect(beforeSendEvent).toHaveBeenCalledTimes(3);
64-
expect(beforeSendEvent).toHaveBeenCalledWith(
65-
expect.objectContaining({
66-
transaction: 'GET /',
67-
}),
68-
expect.any(Object),
69-
);
70-
expect(beforeSendEvent).toHaveBeenCalledWith(
71-
expect.objectContaining({
72-
transaction: 'GET _nuxt/some_asset.js',
73-
}),
74-
expect.any(Object),
75-
);
76-
expect(beforeSendEvent).not.toHaveBeenCalledWith(
77-
expect.objectContaining({
78-
transaction: 'GET /_nuxt/some_asset.js',
79-
}),
80-
expect.any(Object),
81-
);
82-
expect(beforeSendEvent).toHaveBeenCalledWith(
83-
expect.objectContaining({
84-
transaction: 'POST /_server',
85-
}),
86-
expect.any(Object),
69+
it.each(['GET /', 'POST /_server'])(
70+
'does not filter out high quality or route transactions (%s)',
71+
async transaction => {
72+
client.captureEvent({ type: 'transaction', transaction });
73+
await client!.flush();
74+
expect(beforeSendEvent).toHaveBeenCalledWith(
75+
expect.objectContaining({
76+
transaction,
77+
}),
78+
expect.any(Object),
79+
);
80+
},
8781
);
8882
});
8983

0 commit comments

Comments
 (0)