From 475bf92da9a92963aed1e411e4a02498a8ee9673 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 26 Nov 2024 15:49:09 -0500 Subject: [PATCH 1/2] fix(nuxt): Avoid sending resource request transactions --- packages/nuxt/src/server/sdk.ts | 16 +++++--- packages/nuxt/test/server/sdk.test.ts | 58 ++++++++++++--------------- 2 files changed, 36 insertions(+), 38 deletions(-) diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index 6c4dd4712a1a..f26df73dcd98 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -9,6 +9,7 @@ import { import type { Client, EventProcessor, Integration } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; import type { SentryNuxtServerOptions } from '../common/types'; +import * as path from 'node:path'; /** * Initializes the server-side of the Nuxt SDK @@ -33,23 +34,26 @@ export function init(options: SentryNuxtServerOptions): Client | undefined { } /** - * Filter out transactions for Nuxt build assets - * This regex matches the default path to the nuxt-generated build assets (`_nuxt`). + * Filter out transactions for resource requests which we don't want to send to Sentry + * for quota reasons. * * Only exported for testing */ export function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor { return Object.assign( (event => { - if (event.type === 'transaction' && event.transaction?.match(/^GET \/_nuxt\//)) { - // todo: the buildAssetDir could be changed in the nuxt config - change this to a more generic solution + if (event.type !== 'transaction' || !event.transaction) { + return event; + } + // We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out + // path.extname will return an empty string for normal page requests + if (path.extname(event.transaction)) { options.debug && DEBUG_BUILD && logger.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction); return null; - } else { - return event; } + return event; }) satisfies EventProcessor, { id: 'NuxtLowQualityTransactionsFilter' }, ); diff --git a/packages/nuxt/test/server/sdk.test.ts b/packages/nuxt/test/server/sdk.test.ts index 56888afc9a79..611c24e1dcf4 100644 --- a/packages/nuxt/test/server/sdk.test.ts +++ b/packages/nuxt/test/server/sdk.test.ts @@ -45,45 +45,39 @@ describe('Nuxt Server SDK', () => { expect(init({})).not.toBeUndefined(); }); - it('filters out low quality transactions', async () => { + describe('low quality transactions filter (%s)', () => { const beforeSendEvent = vi.fn(event => event); const client = init({ 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 /_nuxt/some_asset.js' }); - // Although this has the name of the build asset directory (_nuxt), it should not be filtered out as it would not match the regex - client.captureEvent({ type: 'transaction', transaction: 'GET _nuxt/some_asset.js' }); - client.captureEvent({ type: 'transaction', transaction: 'POST /_server' }); - - await client!.flush(); + it.each([ + [ + 'GET /_nuxt/some_asset.js', + 'GET _nuxt/some_asset.js', + 'GET /icons/favicon.ico', + 'GET /assets/logo.png', + 'GET /icons/zones/forest.svg', + ], + ])('filters out low quality transactions', async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).not.toHaveBeenCalled(); + }); - expect(beforeSendEvent).toHaveBeenCalledTimes(3); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET _nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).not.toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'GET /_nuxt/some_asset.js', - }), - expect.any(Object), - ); - expect(beforeSendEvent).toHaveBeenCalledWith( - expect.objectContaining({ - transaction: 'POST /_server', - }), - expect.any(Object), + it.each(['GET /', 'POST /_server'])( + 'does not filter out high quality or route transactions (%s)', + async transaction => { + client.captureEvent({ type: 'transaction', transaction }); + await client!.flush(); + expect(beforeSendEvent).toHaveBeenCalledWith( + expect.objectContaining({ + transaction, + }), + expect.any(Object), + ); + }, ); }); From 938471f77591157c406dd5f41edc2e8546b01c32 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 26 Nov 2024 15:51:15 -0500 Subject: [PATCH 2/2] formatting --- packages/nuxt/src/server/sdk.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/server/sdk.ts b/packages/nuxt/src/server/sdk.ts index f26df73dcd98..eab3e4b1a8a0 100644 --- a/packages/nuxt/src/server/sdk.ts +++ b/packages/nuxt/src/server/sdk.ts @@ -1,3 +1,4 @@ +import * as path from 'node:path'; import { applySdkMetadata, flush, getGlobalScope } from '@sentry/core'; import { logger, vercelWaitUntil } from '@sentry/core'; import { @@ -9,7 +10,6 @@ import { import type { Client, EventProcessor, Integration } from '@sentry/types'; import { DEBUG_BUILD } from '../common/debug-build'; import type { SentryNuxtServerOptions } from '../common/types'; -import * as path from 'node:path'; /** * Initializes the server-side of the Nuxt SDK