From b5eafa63ce4441f02b3e303486ce81fed80da212 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 11:47:56 +0000 Subject: [PATCH 1/5] feat(eventprocessors): Add name field to EventProcessor --- packages/hub/src/scope.ts | 16 +++++++++++++++- packages/types/src/eventprocessor.ts | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 09dd244734ee..9ca0ee4a0550 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -18,9 +18,17 @@ import { Transaction, User, } from '@sentry/types'; -import { dateTimestampInSeconds, getGlobalSingleton, isPlainObject, isThenable, SyncPromise } from '@sentry/utils'; +import { + dateTimestampInSeconds, + getGlobalSingleton, + isPlainObject, + isThenable, + SyncPromise, + logger, +} from '@sentry/utils'; import { Session } from './session'; +import { IS_DEBUG_BUILD } from './flags'; /** * Absolute maximum number of breadcrumbs added to an event. @@ -457,6 +465,12 @@ export class Scope implements ScopeInterface { resolve(event); } else { const result = processor({ ...event }, hint) as Event | null; + + IS_DEBUG_BUILD && + processor.name && + result === null && + logger.log(`Event processor ${processor.name} dropped event.`); + if (isThenable(result)) { void result .then(final => this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve)) diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 13727ae2e797..54a84d60dd96 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -6,4 +6,7 @@ import { Event, EventHint } from './event'; * Returning a PromiseLike 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. */ -export type EventProcessor = (event: Event, hint?: EventHint) => PromiseLike | Event | null; +export interface EventProcessor { + name?: string; + (event: Event, hint?: EventHint): PromiseLike | Event | null; +} From 04da60208fe597cd52a8640e4a12733ef658fea1 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 11:57:25 +0000 Subject: [PATCH 2/5] Add example for dedupe integration event processor --- packages/hub/src/scope.ts | 4 ++-- packages/integrations/src/dedupe.ts | 8 ++++++-- packages/types/src/eventprocessor.ts | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 9ca0ee4a0550..f463d17d2b54 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -467,9 +467,9 @@ export class Scope implements ScopeInterface { const result = processor({ ...event }, hint) as Event | null; IS_DEBUG_BUILD && - processor.name && + processor.identifier && result === null && - logger.log(`Event processor ${processor.name} dropped event.`); + logger.log(`Event processor ${processor.identifier} dropped event.`); if (isThenable(result)) { void result diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 644f3d41cd62..26b8d8465795 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor = (currentEvent: Event): Event | null => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,11 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.identifier = 'dedupe-processor'; + + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 54a84d60dd96..7f2ec83f3e65 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -7,6 +7,6 @@ import { Event, EventHint } from './event'; * Event processing will be deferred until your Promise is resolved. */ export interface EventProcessor { - name?: string; + identifier?: string; // This field can't be named "name" because functions already have this field natively (event: Event, hint?: EventHint): PromiseLike | Event | null; } From 105b28df4ed5b2b41fd9920362ff1a90ac39f7db Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 16:12:59 +0000 Subject: [PATCH 3/5] Add identifiers to event processors that drop events --- packages/browser/src/integrations/dedupe.ts | 7 +++++-- .../core/src/integrations/inboundfilters.ts | 7 +++++-- packages/core/test/mocks/integration.ts | 20 +++++++++++-------- packages/hub/src/scope.ts | 8 ++++---- packages/integrations/src/dedupe.ts | 5 ++--- packages/integrations/src/offline.ts | 9 +++++++-- packages/nextjs/src/index.client.ts | 7 ++++++- packages/nextjs/src/index.server.ts | 12 ++++++----- packages/types/src/eventprocessor.ts | 2 +- 9 files changed, 49 insertions(+), 28 deletions(-) diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index c486c84c815e..38e1a1661dda 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((currentEvent: Event) => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -40,7 +40,10 @@ export class Dedupe implements Integration { return (self._previousEvent = currentEvent); } return currentEvent; - }); + }; + + eventProcessor.id = 'DedupeIntegration'; + addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 6151e32e5bbd..60ad4d47c645 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -33,7 +33,7 @@ export class InboundFilters implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (processor: EventProcessor) => void, getCurrentHub: () => Hub): void { - addGlobalEventProcessor((event: Event) => { + const eventProcess: EventProcessor = (event: Event) => { const hub = getCurrentHub(); if (hub) { const self = hub.getIntegration(InboundFilters); @@ -45,7 +45,10 @@ export class InboundFilters implements Integration { } } return event; - }); + }; + + eventProcess.id = 'InboundFiltersIntegration'; + addGlobalEventProcessor(eventProcess); } } diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 465fac64576a..8885a4ed77ad 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -1,6 +1,6 @@ import { getCurrentHub } from '@sentry/hub'; import { configureScope } from '@sentry/minimal'; -import { Event, Integration } from '@sentry/types'; +import { Event, EventProcessor, Integration } from '@sentry/types'; export class TestIntegration implements Integration { public static id: string = 'TestIntegration'; @@ -8,14 +8,18 @@ export class TestIntegration implements Integration { public name: string = 'TestIntegration'; public setupOnce(): void { - configureScope(scope => { - scope.addEventProcessor((event: Event) => { - if (!getCurrentHub().getIntegration(TestIntegration)) { - return event; - } + const eventProcessor: EventProcessor = (event: Event) => { + if (!getCurrentHub().getIntegration(TestIntegration)) { + return event; + } + + return null; + }; - return null; - }); + eventProcessor.id = 'TestIntegration'; + + configureScope(scope => { + scope.addEventProcessor(eventProcessor); }); } } diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index f463d17d2b54..5919c0c4bf01 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -23,12 +23,12 @@ import { getGlobalSingleton, isPlainObject, isThenable, - SyncPromise, logger, + SyncPromise, } from '@sentry/utils'; -import { Session } from './session'; import { IS_DEBUG_BUILD } from './flags'; +import { Session } from './session'; /** * Absolute maximum number of breadcrumbs added to an event. @@ -467,9 +467,9 @@ export class Scope implements ScopeInterface { const result = processor({ ...event }, hint) as Event | null; IS_DEBUG_BUILD && - processor.identifier && + processor.id && result === null && - logger.log(`Event processor ${processor.identifier} dropped event.`); + logger.log(`Event processor "${processor.id}" dropped event`); if (isThenable(result)) { void result diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 26b8d8465795..228241469ffa 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -24,7 +24,7 @@ export class Dedupe implements Integration { * @inheritDoc */ public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void { - const eventProcessor = (currentEvent: Event): Event | null => { + const eventProcessor: EventProcessor = currentEvent => { const self = getCurrentHub().getIntegration(Dedupe); if (self) { // Juuust in case something goes wrong @@ -42,8 +42,7 @@ export class Dedupe implements Integration { return currentEvent; }; - eventProcessor.identifier = 'dedupe-processor'; - + eventProcessor.id = 'DedupeIntegration'; addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index 0d2da0841805..d8706330b52e 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -80,10 +80,12 @@ export class Offline implements Integration { }); } - addGlobalEventProcessor((event: Event) => { + const eventProcessor: EventProcessor = event => { if (this.hub && this.hub.getIntegration(Offline)) { // cache if we are positively offline if ('navigator' in this.global && 'onLine' in this.global.navigator && !this.global.navigator.onLine) { + IS_DEBUG_BUILD && logger.log('Event dropped due to being a offline - caching instead'); + void this._cacheEvent(event) .then((_event: Event): Promise => this._enforceMaxEvents()) .catch((_error): void => { @@ -96,7 +98,10 @@ export class Offline implements Integration { } return event; - }); + }; + + eventProcessor.id = 'OfflineIntegration'; + addGlobalEventProcessor(eventProcessor); // if online now, send any events stored in a previous offline session if ('navigator' in this.global && 'onLine' in this.global.navigator && this.global.navigator.onLine) { diff --git a/packages/nextjs/src/index.client.ts b/packages/nextjs/src/index.client.ts index 817f8ad3ca56..05b4dc64a3f3 100644 --- a/packages/nextjs/src/index.client.ts +++ b/packages/nextjs/src/index.client.ts @@ -1,5 +1,6 @@ import { configureScope, init as reactInit, Integrations as BrowserIntegrations } from '@sentry/react'; import { BrowserTracing, defaultRequestInstrumentationOptions } from '@sentry/tracing'; +import { EventProcessor } from '@sentry/types'; import { nextRouterInstrumentation } from './performance/client'; import { buildMetadata } from './utils/metadata'; @@ -42,9 +43,13 @@ export function init(options: NextjsOptions): void { ...options, integrations, }); + configureScope(scope => { scope.setTag('runtime', 'browser'); - scope.addEventProcessor(event => (event.type === 'transaction' && event.transaction === '/404' ? null : event)); + const filterTransactions: EventProcessor = event => + event.type === 'transaction' && event.transaction === '/404' ? null : event; + filterTransactions.id = 'NextClient404Filter'; + scope.addEventProcessor(filterTransactions); }); } diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index a57ee89443a5..95829eedb650 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -2,7 +2,7 @@ import { Carrier, getHubFromCarrier, getMainCarrier } from '@sentry/hub'; import { RewriteFrames } from '@sentry/integrations'; import { configureScope, getCurrentHub, init as nodeInit, Integrations } from '@sentry/node'; import { hasTracingEnabled } from '@sentry/tracing'; -import { Event } from '@sentry/types'; +import { Event, EventProcessor } from '@sentry/types'; import { escapeStringForRegex, logger } from '@sentry/utils'; import * as domainModule from 'domain'; import * as path from 'path'; @@ -71,6 +71,12 @@ export function init(options: NextjsOptions): void { nodeInit(options); + const filterTransactions: EventProcessor = event => { + return event.type === 'transaction' && event.transaction === '/404' ? null : event; + }; + + filterTransactions.id = 'NextServer404Filter'; + configureScope(scope => { scope.setTag('runtime', 'node'); if (isVercel) { @@ -131,10 +137,6 @@ function addServerIntegrations(options: NextjsOptions): void { } } -function filterTransactions(event: Event): Event | null { - return event.type === 'transaction' && event.transaction === '/404' ? null : event; -} - export { withSentryConfig } from './config'; export { SentryWebpackPluginOptions } from './config/types'; export { withSentry } from './utils/withSentry'; diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 7f2ec83f3e65..22bd74f0ab73 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -7,6 +7,6 @@ import { Event, EventHint } from './event'; * Event processing will be deferred until your Promise is resolved. */ export interface EventProcessor { - identifier?: string; // This field can't be named "name" because functions already have this field natively + id?: string; // This field can't be named "name" because functions already have this field natively (event: Event, hint?: EventHint): PromiseLike | Event | null; } From c0f1eadcfb1be6d3666f0070668890f9daba34fd Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Wed, 13 Apr 2022 16:40:36 +0000 Subject: [PATCH 4/5] Make tsc happy --- packages/nextjs/src/index.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nextjs/src/index.server.ts b/packages/nextjs/src/index.server.ts index 95829eedb650..8af32bbed853 100644 --- a/packages/nextjs/src/index.server.ts +++ b/packages/nextjs/src/index.server.ts @@ -2,7 +2,7 @@ import { Carrier, getHubFromCarrier, getMainCarrier } from '@sentry/hub'; import { RewriteFrames } from '@sentry/integrations'; import { configureScope, getCurrentHub, init as nodeInit, Integrations } from '@sentry/node'; import { hasTracingEnabled } from '@sentry/tracing'; -import { Event, EventProcessor } from '@sentry/types'; +import { EventProcessor } from '@sentry/types'; import { escapeStringForRegex, logger } from '@sentry/utils'; import * as domainModule from 'domain'; import * as path from 'path'; From 8ae594cd2c80765a44591a44089d6b6501d2616b Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 14 Apr 2022 07:36:14 +0000 Subject: [PATCH 5/5] Use this.name where applicable --- packages/browser/src/integrations/dedupe.ts | 2 +- packages/core/src/integrations/inboundfilters.ts | 2 +- packages/core/test/mocks/integration.ts | 2 +- packages/integrations/src/dedupe.ts | 2 +- packages/integrations/src/offline.ts | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/browser/src/integrations/dedupe.ts b/packages/browser/src/integrations/dedupe.ts index 38e1a1661dda..48aa8411f268 100644 --- a/packages/browser/src/integrations/dedupe.ts +++ b/packages/browser/src/integrations/dedupe.ts @@ -42,7 +42,7 @@ export class Dedupe implements Integration { return currentEvent; }; - eventProcessor.id = 'DedupeIntegration'; + eventProcessor.id = this.name; addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/core/src/integrations/inboundfilters.ts b/packages/core/src/integrations/inboundfilters.ts index 60ad4d47c645..0e9dc859a3f8 100644 --- a/packages/core/src/integrations/inboundfilters.ts +++ b/packages/core/src/integrations/inboundfilters.ts @@ -47,7 +47,7 @@ export class InboundFilters implements Integration { return event; }; - eventProcess.id = 'InboundFiltersIntegration'; + eventProcess.id = this.name; addGlobalEventProcessor(eventProcess); } } diff --git a/packages/core/test/mocks/integration.ts b/packages/core/test/mocks/integration.ts index 8885a4ed77ad..8b95b5673af8 100644 --- a/packages/core/test/mocks/integration.ts +++ b/packages/core/test/mocks/integration.ts @@ -16,7 +16,7 @@ export class TestIntegration implements Integration { return null; }; - eventProcessor.id = 'TestIntegration'; + eventProcessor.id = this.name; configureScope(scope => { scope.addEventProcessor(eventProcessor); diff --git a/packages/integrations/src/dedupe.ts b/packages/integrations/src/dedupe.ts index 228241469ffa..a29223f6832b 100644 --- a/packages/integrations/src/dedupe.ts +++ b/packages/integrations/src/dedupe.ts @@ -42,7 +42,7 @@ export class Dedupe implements Integration { return currentEvent; }; - eventProcessor.id = 'DedupeIntegration'; + eventProcessor.id = this.name; addGlobalEventProcessor(eventProcessor); } } diff --git a/packages/integrations/src/offline.ts b/packages/integrations/src/offline.ts index d8706330b52e..78d8ead05dd4 100644 --- a/packages/integrations/src/offline.ts +++ b/packages/integrations/src/offline.ts @@ -100,7 +100,7 @@ export class Offline implements Integration { return event; }; - eventProcessor.id = 'OfflineIntegration'; + eventProcessor.id = this.name; addGlobalEventProcessor(eventProcessor); // if online now, send any events stored in a previous offline session