From d030a1f62f83807dd2945cb1ded2e5e5bddcd296 Mon Sep 17 00:00:00 2001 From: Shardul Natu <43422294+kiranani@users.noreply.github.com> Date: Mon, 15 Dec 2025 09:40:54 -0800 Subject: [PATCH] update(telemetry): add hashed_extension_name to field to extension events (#15025) Co-authored-by: Shnatu --- packages/cli/src/config/extension-manager.ts | 9 +++++++-- packages/cli/src/config/extension.test.ts | 4 ++++ .../clearcut-logger/clearcut-logger.ts | 10 +++++----- packages/core/src/telemetry/loggers.test.ts | 17 +++++++++++++++-- packages/core/src/telemetry/types.ts | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/config/extension-manager.ts b/packages/cli/src/config/extension-manager.ts index 796867c614..d64543956f 100644 --- a/packages/cli/src/config/extension-manager.ts +++ b/packages/cli/src/config/extension-manager.ts @@ -327,6 +327,7 @@ export class ExtensionManager extends ExtensionLoader { await logExtensionUpdateEvent( this.telemetryConfig, new ExtensionUpdateEvent( + newExtensionConfig.name, hashValue(newExtensionConfig.name), getExtensionId(newExtensionConfig, installMetadata), newExtensionConfig.version, @@ -339,6 +340,7 @@ export class ExtensionManager extends ExtensionLoader { await logExtensionInstallEvent( this.telemetryConfig, new ExtensionInstallEvent( + newExtensionConfig.name, hashValue(newExtensionConfig.name), getExtensionId(newExtensionConfig, installMetadata), newExtensionConfig.version, @@ -375,6 +377,7 @@ export class ExtensionManager extends ExtensionLoader { await logExtensionUpdateEvent( this.telemetryConfig, new ExtensionUpdateEvent( + config?.name ?? '', hashValue(config?.name ?? ''), extensionId ?? '', newExtensionConfig?.version ?? '', @@ -387,6 +390,7 @@ export class ExtensionManager extends ExtensionLoader { await logExtensionInstallEvent( this.telemetryConfig, new ExtensionInstallEvent( + newExtensionConfig?.name ?? '', hashValue(newExtensionConfig?.name ?? ''), extensionId ?? '', newExtensionConfig?.version ?? '', @@ -434,6 +438,7 @@ export class ExtensionManager extends ExtensionLoader { await logExtensionUninstall( this.telemetryConfig, new ExtensionUninstallEvent( + extension.name, hashValue(extension.name), extension.id, 'success', @@ -716,7 +721,7 @@ export class ExtensionManager extends ExtensionLoader { } await logExtensionDisable( this.telemetryConfig, - new ExtensionDisableEvent(hashValue(name), extension.id, scope), + new ExtensionDisableEvent(name, hashValue(name), extension.id, scope), ); if (!this.config || this.config.getEnableExtensionReloading()) { // Only toggle the isActive state if we are actually going to disable it @@ -751,7 +756,7 @@ export class ExtensionManager extends ExtensionLoader { } await logExtensionEnable( this.telemetryConfig, - new ExtensionEnableEvent(hashValue(name), extension.id, scope), + new ExtensionEnableEvent(name, hashValue(name), extension.id, scope), ); if (!this.config || this.config.getEnableExtensionReloading()) { // Only toggle the isActive state if we are actually going to disable it diff --git a/packages/cli/src/config/extension.test.ts b/packages/cli/src/config/extension.test.ts index ffef6f794f..73fcc08f2a 100644 --- a/packages/cli/src/config/extension.test.ts +++ b/packages/cli/src/config/extension.test.ts @@ -1771,6 +1771,7 @@ This extension will run the following MCP servers: } else { expect(mockLogExtensionUninstall).toHaveBeenCalled(); expect(ExtensionUninstallEvent).toHaveBeenCalledWith( + 'my-local-extension', hashValue('my-local-extension'), hashValue(userExtensionsDir), 'success', @@ -1818,6 +1819,7 @@ This extension will run the following MCP servers: expect(fs.existsSync(sourceExtDir)).toBe(false); expect(mockLogExtensionUninstall).toHaveBeenCalled(); expect(ExtensionUninstallEvent).toHaveBeenCalledWith( + 'gemini-sql-extension', hashValue('gemini-sql-extension'), hashValue('https://github.com/google/gemini-sql-extension'), 'success', @@ -1935,6 +1937,7 @@ This extension will run the following MCP servers: expect(mockLogExtensionDisable).toHaveBeenCalled(); expect(ExtensionDisableEvent).toHaveBeenCalledWith( + 'ext1', hashValue('ext1'), hashValue(userExtensionsDir), SettingScope.Workspace, @@ -2002,6 +2005,7 @@ This extension will run the following MCP servers: expect(mockLogExtensionEnable).toHaveBeenCalled(); expect(ExtensionEnableEvent).toHaveBeenCalledWith( + 'ext1', hashValue('ext1'), hashValue(userExtensionsDir), SettingScope.Workspace, diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts index b5f6639504..e4535fdf48 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts @@ -1017,7 +1017,7 @@ export class ClearcutLogger { const data: EventValue[] = [ { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME, - value: event.extension_name, + value: event.hashed_extension_name, }, { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_ID, @@ -1051,7 +1051,7 @@ export class ClearcutLogger { const data: EventValue[] = [ { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME, - value: event.extension_name, + value: event.hashed_extension_name, }, { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_ID, @@ -1075,7 +1075,7 @@ export class ClearcutLogger { const data: EventValue[] = [ { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME, - value: event.extension_name, + value: event.hashed_extension_name, }, { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_ID, @@ -1175,7 +1175,7 @@ export class ClearcutLogger { const data: EventValue[] = [ { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME, - value: event.extension_name, + value: event.hashed_extension_name, }, { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_ID, @@ -1214,7 +1214,7 @@ export class ClearcutLogger { const data: EventValue[] = [ { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_NAME, - value: event.extension_name, + value: event.hashed_extension_name, }, { gemini_cli_key: EventMetadataKey.GEMINI_CLI_EXTENSION_ID, diff --git a/packages/core/src/telemetry/loggers.test.ts b/packages/core/src/telemetry/loggers.test.ts index 27897b2f2e..a7b89d1003 100644 --- a/packages/core/src/telemetry/loggers.test.ts +++ b/packages/core/src/telemetry/loggers.test.ts @@ -1760,6 +1760,7 @@ describe('loggers', () => { it('should log extension install event', async () => { const event = new ExtensionInstallEvent( 'testing', + 'testing-hash', 'testing-id', '0.1.0', 'git', @@ -1810,6 +1811,7 @@ describe('loggers', () => { it('should log extension update event', async () => { const event = new ExtensionUpdateEvent( 'testing', + 'testing-hash', 'testing-id', '0.1.0', '0.1.1', @@ -1861,6 +1863,7 @@ describe('loggers', () => { it('should log extension uninstall event', async () => { const event = new ExtensionUninstallEvent( 'testing', + 'testing-hash', 'testing-id', 'success', ); @@ -1903,7 +1906,12 @@ describe('loggers', () => { }); it('should log extension enable event', async () => { - const event = new ExtensionEnableEvent('testing', 'testing-id', 'user'); + const event = new ExtensionEnableEvent( + 'testing', + 'testing-hash', + 'testing-id', + 'user', + ); await logExtensionEnable(mockConfig, event); @@ -1943,7 +1951,12 @@ describe('loggers', () => { }); it('should log extension disable event', async () => { - const event = new ExtensionDisableEvent('testing', 'testing-id', 'user'); + const event = new ExtensionDisableEvent( + 'testing', + 'testing-hash', + 'testing-id', + 'user', + ); await logExtensionDisable(mockConfig, event); diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index 701bd09fcb..95893f34d0 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -1231,6 +1231,7 @@ export class ExtensionInstallEvent implements BaseTelemetryEvent { 'event.name': 'extension_install'; 'event.timestamp': string; extension_name: string; + hashed_extension_name: string; extension_id: string; extension_version: string; extension_source: string; @@ -1238,6 +1239,7 @@ export class ExtensionInstallEvent implements BaseTelemetryEvent { constructor( extension_name: string, + hashed_extension_name: string, extension_id: string, extension_version: string, extension_source: string, @@ -1246,6 +1248,7 @@ export class ExtensionInstallEvent implements BaseTelemetryEvent { this['event.name'] = 'extension_install'; this['event.timestamp'] = new Date().toISOString(); this.extension_name = extension_name; + this.hashed_extension_name = hashed_extension_name; this.extension_id = extension_id; this.extension_version = extension_version; this.extension_source = extension_source; @@ -1325,17 +1328,20 @@ export class ExtensionUninstallEvent implements BaseTelemetryEvent { 'event.name': 'extension_uninstall'; 'event.timestamp': string; extension_name: string; + hashed_extension_name: string; extension_id: string; status: 'success' | 'error'; constructor( extension_name: string, + hashed_extension_name: string, extension_id: string, status: 'success' | 'error', ) { this['event.name'] = 'extension_uninstall'; this['event.timestamp'] = new Date().toISOString(); this.extension_name = extension_name; + this.hashed_extension_name = hashed_extension_name; this.extension_id = extension_id; this.status = status; } @@ -1360,6 +1366,7 @@ export class ExtensionUpdateEvent implements BaseTelemetryEvent { 'event.name': 'extension_update'; 'event.timestamp': string; extension_name: string; + hashed_extension_name: string; extension_id: string; extension_previous_version: string; extension_version: string; @@ -1368,6 +1375,7 @@ export class ExtensionUpdateEvent implements BaseTelemetryEvent { constructor( extension_name: string, + hashed_extension_name: string, extension_id: string, extension_version: string, extension_previous_version: string, @@ -1377,6 +1385,7 @@ export class ExtensionUpdateEvent implements BaseTelemetryEvent { this['event.name'] = 'extension_update'; this['event.timestamp'] = new Date().toISOString(); this.extension_name = extension_name; + this.hashed_extension_name = hashed_extension_name; this.extension_id = extension_id; this.extension_version = extension_version; this.extension_previous_version = extension_previous_version; @@ -1407,17 +1416,20 @@ export class ExtensionEnableEvent implements BaseTelemetryEvent { 'event.name': 'extension_enable'; 'event.timestamp': string; extension_name: string; + hashed_extension_name: string; extension_id: string; setting_scope: string; constructor( extension_name: string, + hashed_extension_name: string, extension_id: string, settingScope: string, ) { this['event.name'] = 'extension_enable'; this['event.timestamp'] = new Date().toISOString(); this.extension_name = extension_name; + this.hashed_extension_name = hashed_extension_name; this.extension_id = extension_id; this.setting_scope = settingScope; } @@ -1543,17 +1555,20 @@ export class ExtensionDisableEvent implements BaseTelemetryEvent { 'event.name': 'extension_disable'; 'event.timestamp': string; extension_name: string; + hashed_extension_name: string; extension_id: string; setting_scope: string; constructor( extension_name: string, + hashed_extension_name: string, extension_id: string, settingScope: string, ) { this['event.name'] = 'extension_disable'; this['event.timestamp'] = new Date().toISOString(); this.extension_name = extension_name; + this.hashed_extension_name = hashed_extension_name; this.extension_id = extension_id; this.setting_scope = settingScope; }