From 382c30240f563e58bc4d4832557c6825da40ce7f Mon Sep 17 00:00:00 2001 From: panteliselef Date: Wed, 26 Feb 2025 22:00:37 +0200 Subject: [PATCH] feat(nextjs): Track usage of pages and app router (#5236) --- .changeset/eighty-emus-smile.md | 5 +++++ .changeset/tricky-rings-trade.md | 5 +++++ .../src/app-router/client/ClerkProvider.tsx | 2 ++ packages/nextjs/src/pages/ClerkProvider.tsx | 2 ++ packages/nextjs/src/utils/router-telemetry.ts | 22 +++++++++++++++++++ packages/shared/src/telemetry/collector.ts | 11 +++++----- .../telemetry/events/framework-metadata.ts | 17 ++++++++++++++ packages/shared/src/telemetry/events/index.ts | 1 + 8 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 .changeset/eighty-emus-smile.md create mode 100644 .changeset/tricky-rings-trade.md create mode 100644 packages/nextjs/src/utils/router-telemetry.ts create mode 100644 packages/shared/src/telemetry/events/framework-metadata.ts diff --git a/.changeset/eighty-emus-smile.md b/.changeset/eighty-emus-smile.md new file mode 100644 index 00000000000..004ffb05bf1 --- /dev/null +++ b/.changeset/eighty-emus-smile.md @@ -0,0 +1,5 @@ +--- +'@clerk/nextjs': patch +--- + +Track usage of pages and app router. diff --git a/.changeset/tricky-rings-trade.md b/.changeset/tricky-rings-trade.md new file mode 100644 index 00000000000..92eba9abb18 --- /dev/null +++ b/.changeset/tricky-rings-trade.md @@ -0,0 +1,5 @@ +--- +'@clerk/shared': patch +--- + +Update `TelemetryCollector` to throttle events after they've been sampled. diff --git a/packages/nextjs/src/app-router/client/ClerkProvider.tsx b/packages/nextjs/src/app-router/client/ClerkProvider.tsx index c12109385ca..55f9292ac45 100644 --- a/packages/nextjs/src/app-router/client/ClerkProvider.tsx +++ b/packages/nextjs/src/app-router/client/ClerkProvider.tsx @@ -13,6 +13,7 @@ import type { NextClerkProviderProps } from '../../types'; import { ClerkJSScript } from '../../utils/clerk-js-script'; import { canUseKeyless } from '../../utils/feature-flags'; import { mergeNextClerkPropsWithEnv } from '../../utils/mergeNextClerkPropsWithEnv'; +import { RouterTelemetry } from '../../utils/router-telemetry'; import { isNextWithUnstableServerActions } from '../../utils/sdk-versions'; import { invalidateCacheAction } from '../server-actions'; import { useAwaitablePush } from './useAwaitablePush'; @@ -107,6 +108,7 @@ const NextClientClerkProvider = (props: NextClerkProviderProps) => { return ( + {children} diff --git a/packages/nextjs/src/pages/ClerkProvider.tsx b/packages/nextjs/src/pages/ClerkProvider.tsx index 1c15cd31fe8..10f5d774856 100644 --- a/packages/nextjs/src/pages/ClerkProvider.tsx +++ b/packages/nextjs/src/pages/ClerkProvider.tsx @@ -11,6 +11,7 @@ import { ClerkJSScript } from '../utils/clerk-js-script'; import { invalidateNextRouterCache } from '../utils/invalidateNextRouterCache'; import { mergeNextClerkPropsWithEnv } from '../utils/mergeNextClerkPropsWithEnv'; import { removeBasePath } from '../utils/removeBasePath'; +import { RouterTelemetry } from '../utils/router-telemetry'; setErrorThrowerOptions({ packageName: PACKAGE_NAME }); setClerkJsLoadingErrorPackageName(PACKAGE_NAME); @@ -53,6 +54,7 @@ export function ClerkProvider({ children, ...props }: NextClerkProviderProps): J {...mergedProps} initialState={initialState} > + {children} diff --git a/packages/nextjs/src/utils/router-telemetry.ts b/packages/nextjs/src/utils/router-telemetry.ts new file mode 100644 index 00000000000..88f785cbde1 --- /dev/null +++ b/packages/nextjs/src/utils/router-telemetry.ts @@ -0,0 +1,22 @@ +import { eventFrameworkMetadata } from '@clerk/shared/telemetry'; + +import { useClerk } from '../client-boundary/hooks'; +import { usePagesRouter } from '../client-boundary/hooks/usePagesRouter'; + +const RouterTelemetry = () => { + const clerk = useClerk(); + const { pagesRouter } = usePagesRouter(); + + /** + * Caching and throttling is handled internally it's safe to execute on every navigation. + */ + clerk.telemetry?.record( + eventFrameworkMetadata({ + router: pagesRouter ? 'pages' : 'app', + }), + ); + + return null; +}; + +export { RouterTelemetry }; diff --git a/packages/shared/src/telemetry/collector.ts b/packages/shared/src/telemetry/collector.ts index 8c448268421..78e8b622583 100644 --- a/packages/shared/src/telemetry/collector.ts +++ b/packages/shared/src/telemetry/collector.ts @@ -135,14 +135,15 @@ export class TelemetryCollector implements TelemetryCollectorInterface { #shouldBeSampled(preparedPayload: TelemetryEvent, eventSamplingRate?: number) { const randomSeed = Math.random(); - if (this.#eventThrottler.isEventThrottled(preparedPayload)) { + const toBeSampled = + randomSeed <= this.#config.samplingRate && + (typeof eventSamplingRate === 'undefined' || randomSeed <= eventSamplingRate); + + if (!toBeSampled) { return false; } - return ( - randomSeed <= this.#config.samplingRate && - (typeof eventSamplingRate === 'undefined' || randomSeed <= eventSamplingRate) - ); + return !this.#eventThrottler.isEventThrottled(preparedPayload); } #scheduleFlush(): void { diff --git a/packages/shared/src/telemetry/events/framework-metadata.ts b/packages/shared/src/telemetry/events/framework-metadata.ts new file mode 100644 index 00000000000..1a5f69e187e --- /dev/null +++ b/packages/shared/src/telemetry/events/framework-metadata.ts @@ -0,0 +1,17 @@ +import type { TelemetryEventRaw } from '@clerk/types'; + +const EVENT_FRAMEWORK_METADATA = 'FRAMEWORK_METADATA'; +const EVENT_SAMPLING_RATE = 0.1; + +type EventFrameworkMetadata = Record; + +/** + * Fired when a helper method is called from a Clerk SDK. + */ +export function eventFrameworkMetadata(payload: EventFrameworkMetadata): TelemetryEventRaw { + return { + event: EVENT_FRAMEWORK_METADATA, + eventSamplingRate: EVENT_SAMPLING_RATE, + payload, + }; +} diff --git a/packages/shared/src/telemetry/events/index.ts b/packages/shared/src/telemetry/events/index.ts index 1957f6d4f20..e9ad6ca4ceb 100644 --- a/packages/shared/src/telemetry/events/index.ts +++ b/packages/shared/src/telemetry/events/index.ts @@ -1,2 +1,3 @@ export * from './component-mounted'; export * from './method-called'; +export * from './framework-metadata';