From 6365eaa5b839db49a3e27ce94ad95da5f4ea9bfb Mon Sep 17 00:00:00 2001 From: Andy Bitz Date: Thu, 26 Feb 2026 20:41:31 +0100 Subject: [PATCH 1/3] Update event reporting for control rewrite --- .../vercel-flags-core/src/black-box.test.ts | 51 +++++++++++++++++++ .../vercel-flags-core/src/controller/index.ts | 7 +++ .../src/utils/usage-tracker.ts | 23 ++++++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/packages/vercel-flags-core/src/black-box.test.ts b/packages/vercel-flags-core/src/black-box.test.ts index f8ca008a..d4420464 100644 --- a/packages/vercel-flags-core/src/black-box.test.ts +++ b/packages/vercel-flags-core/src/black-box.test.ts @@ -205,6 +205,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'build', + revision: 1, + environment: 'test', }, }, ]), @@ -246,6 +249,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'build', + revision: 1, + environment: 'test', }, }, ]), @@ -346,6 +352,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -420,6 +429,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'build', + revision: 1, + environment: 'test', }, }, ]), @@ -1189,6 +1201,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'offline', + revision: 1, + environment: 'test', }, }, ]), @@ -1265,6 +1280,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'offline', + revision: 1, + environment: 'test', }, }, ]), @@ -2126,6 +2144,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -2497,6 +2518,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 2000, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -3166,6 +3190,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -3229,6 +3256,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, { @@ -3241,6 +3271,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, { @@ -3253,6 +3286,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -3405,6 +3441,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'offline', + revision: 1, + environment: 'test', }, }, ]), @@ -3624,6 +3663,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 2, + mode: 'build', + revision: 2, + environment: 'test', }, }, ]), @@ -3665,6 +3707,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 1, + mode: 'build', + revision: 1, + environment: 'test', }, }, ]), @@ -3728,6 +3773,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 5, + mode: 'stream', + revision: 1, + environment: 'test', }, }, ]), @@ -3784,6 +3832,9 @@ describe('Controller (black-box)', () => { cacheIsBlocking: false, duration: 0, configUpdatedAt: 2, + mode: 'build', + revision: 2, + environment: 'test', }, }, ]), diff --git a/packages/vercel-flags-core/src/controller/index.ts b/packages/vercel-flags-core/src/controller/index.ts index d0dbe929..ee8bc35c 100644 --- a/packages/vercel-flags-core/src/controller/index.ts +++ b/packages/vercel-flags-core/src/controller/index.ts @@ -784,17 +784,24 @@ export class Controller implements ControllerInterface { : this.state === 'polling' ? 'REFRESHING' : 'NONE'; + const mode = this.mode; const trackOptions: TrackReadOptions = { configOrigin, cacheStatus: cacheHadDefinitions ? 'HIT' : 'MISS', cacheAction, cacheIsBlocking: !cacheHadDefinitions, duration: Date.now() - startTime, + mode: + mode === 'streaming' ? 'stream' : mode === 'polling' ? 'poll' : mode, }; const configUpdatedAt = this.data?.configUpdatedAt; if (typeof configUpdatedAt === 'number') { trackOptions.configUpdatedAt = configUpdatedAt; } + const revision = this.data?.revision; + if (typeof revision === 'number') { + trackOptions.revision = revision; + } if (isFirstRead) { trackOptions.cacheIsFirstRead = true; } diff --git a/packages/vercel-flags-core/src/utils/usage-tracker.ts b/packages/vercel-flags-core/src/utils/usage-tracker.ts index 1d6c5654..657379f1 100644 --- a/packages/vercel-flags-core/src/utils/usage-tracker.ts +++ b/packages/vercel-flags-core/src/utils/usage-tracker.ts @@ -18,13 +18,16 @@ export interface FlagsConfigReadEvent { region?: string; invocationHost?: string; vercelRequestId?: string; - cacheStatus?: 'HIT' | 'MISS' | 'BYPASS'; + cacheStatus?: 'HIT' | 'MISS' | 'BYPASS' | 'STALE'; cacheAction?: 'REFRESHING' | 'FOLLOWING' | 'NONE'; cacheIsBlocking?: boolean; cacheIsFirstRead?: boolean; duration?: number; configUpdatedAt?: number; - configOrigin?: 'in-memory' | 'embedded'; + configOrigin?: 'in-memory' | 'embedded' | 'poll' | 'stream' | 'constructor'; + mode?: 'poll' | 'stream' | 'build' | 'offline'; + revision?: number; + environment?: string; }; } @@ -91,6 +94,10 @@ export interface TrackReadOptions { duration?: number; /** Timestamp when the config was last updated */ configUpdatedAt?: number; + /** The mode the SDK is operating in */ + mode?: 'poll' | 'stream' | 'build' | 'offline'; + /** Revision of the config */ + revision?: number; } /** @@ -174,6 +181,18 @@ export class UsageTracker { if (options.configUpdatedAt !== undefined) { event.payload.configUpdatedAt = options.configUpdatedAt; } + if (options.mode !== undefined) { + event.payload.mode = options.mode; + } + if (options.revision !== undefined) { + event.payload.revision = options.revision; + } + } + + const environment = + process.env.VERCEL_ENV || process.env.NODE_ENV || undefined; + if (environment) { + event.payload.environment = environment; } this.batcher.events.push(event); From 0de397b811215bd83fc973696a6152000eaf4551 Mon Sep 17 00:00:00 2001 From: Andy Bitz Date: Thu, 26 Feb 2026 20:57:58 +0100 Subject: [PATCH 2/3] Log ingest response --- packages/vercel-flags-core/src/utils/usage-tracker.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vercel-flags-core/src/utils/usage-tracker.ts b/packages/vercel-flags-core/src/utils/usage-tracker.ts index 657379f1..215b8544 100644 --- a/packages/vercel-flags-core/src/utils/usage-tracker.ts +++ b/packages/vercel-flags-core/src/utils/usage-tracker.ts @@ -285,6 +285,7 @@ export class UsageTracker { debugLog( '@vercel/flags-core: Failed to send events:', response.statusText, + await response.text(), ); this.requeue(eventsToSend); } From 5936b4a8447f48b79e3d2381c800f1cd667983f0 Mon Sep 17 00:00:00 2001 From: Andy Bitz Date: Thu, 26 Feb 2026 21:10:34 +0100 Subject: [PATCH 3/3] Use string for revision --- .../vercel-flags-core/src/black-box.test.ts | 34 +++++++++---------- .../src/utils/usage-tracker.ts | 4 +-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/vercel-flags-core/src/black-box.test.ts b/packages/vercel-flags-core/src/black-box.test.ts index d4420464..b4b5b38a 100644 --- a/packages/vercel-flags-core/src/black-box.test.ts +++ b/packages/vercel-flags-core/src/black-box.test.ts @@ -206,7 +206,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'build', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -250,7 +250,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'build', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -353,7 +353,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -430,7 +430,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'build', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -1202,7 +1202,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'offline', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -1281,7 +1281,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'offline', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -2145,7 +2145,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -2519,7 +2519,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 2000, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3191,7 +3191,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3257,7 +3257,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3272,7 +3272,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3287,7 +3287,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3442,7 +3442,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'offline', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3664,7 +3664,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 2, mode: 'build', - revision: 2, + revision: '2', environment: 'test', }, }, @@ -3708,7 +3708,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 1, mode: 'build', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3774,7 +3774,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 5, mode: 'stream', - revision: 1, + revision: '1', environment: 'test', }, }, @@ -3833,7 +3833,7 @@ describe('Controller (black-box)', () => { duration: 0, configUpdatedAt: 2, mode: 'build', - revision: 2, + revision: '2', environment: 'test', }, }, diff --git a/packages/vercel-flags-core/src/utils/usage-tracker.ts b/packages/vercel-flags-core/src/utils/usage-tracker.ts index 215b8544..63436ec6 100644 --- a/packages/vercel-flags-core/src/utils/usage-tracker.ts +++ b/packages/vercel-flags-core/src/utils/usage-tracker.ts @@ -26,7 +26,7 @@ export interface FlagsConfigReadEvent { configUpdatedAt?: number; configOrigin?: 'in-memory' | 'embedded' | 'poll' | 'stream' | 'constructor'; mode?: 'poll' | 'stream' | 'build' | 'offline'; - revision?: number; + revision?: string; environment?: string; }; } @@ -185,7 +185,7 @@ export class UsageTracker { event.payload.mode = options.mode; } if (options.revision !== undefined) { - event.payload.revision = options.revision; + event.payload.revision = String(options.revision); } }