diff --git a/docs/cli/telemetry.md b/docs/cli/telemetry.md index 4b218cb8bd..83af027399 100644 --- a/docs/cli/telemetry.md +++ b/docs/cli/telemetry.md @@ -251,6 +251,9 @@ Captures startup configuration and user prompt submissions. - `debug_mode` (boolean) - `mcp_servers` (string) - `mcp_servers_count` (int) + - `extensions` (string) + - `extension_ids` (string) + - `extension_count` (int) - `mcp_tools` (string, if applicable) - `mcp_tools_count` (int, if applicable) - `output_format` ("text", "json", or "stream-json") diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts index 7651c87a15..36bee1fc0c 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts @@ -479,6 +479,7 @@ export class ClearcutLogger { EventMetadataKey.GEMINI_CLI_START_SESSION_EXTENSIONS_COUNT, value: event.extensions_count.toString(), }, + // We deliberately do not log the names of extensions here, to be safe. { gemini_cli_key: EventMetadataKey.GEMINI_CLI_START_SESSION_EXTENSION_IDS, value: event.extension_ids.toString(), diff --git a/packages/core/src/telemetry/loggers.test.ts b/packages/core/src/telemetry/loggers.test.ts index 0988a84218..63596a4952 100644 --- a/packages/core/src/telemetry/loggers.test.ts +++ b/packages/core/src/telemetry/loggers.test.ts @@ -92,6 +92,7 @@ import * as metrics from './metrics.js'; import { FileOperation } from './metrics.js'; import * as sdk from './sdk.js'; import { vi, describe, beforeEach, it, expect, afterEach } from 'vitest'; +import { type GeminiCLIExtension } from '@google/gemini-cli-core'; import { FinishReason, type CallableTool, @@ -200,7 +201,11 @@ describe('loggers', () => { getTargetDir: () => 'target-dir', getProxy: () => 'http://test.proxy.com:8080', getOutputFormat: () => OutputFormat.JSON, - getExtensions: () => [], + getExtensions: () => + [ + { name: 'ext-one', id: 'id-one' }, + { name: 'ext-two', id: 'id-two' }, + ] as GeminiCLIExtension[], } as unknown as Config; const startSessionEvent = new StartSessionEvent(mockConfig); @@ -229,8 +234,9 @@ describe('loggers', () => { mcp_tools: undefined, mcp_tools_count: undefined, output_format: 'json', - extension_ids: '', - extensions_count: 0, + extension_ids: 'id-one,id-two', + extensions_count: 2, + extensions: 'ext-one,ext-two', auth_type: 'vertex-ai', }, }); diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index a3aa5426b8..b235bb409c 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -67,6 +67,7 @@ export class StartSessionEvent implements BaseTelemetryEvent { mcp_tools?: string; output_format: OutputFormat; extensions_count: number; + extensions: string; extension_ids: string; auth_type?: string; @@ -102,6 +103,7 @@ export class StartSessionEvent implements BaseTelemetryEvent { this.output_format = config.getOutputFormat(); const extensions = config.getExtensions(); this.extensions_count = extensions.length; + this.extensions = extensions.map((e) => e.name).join(','); this.extension_ids = extensions.map((e) => e.id).join(','); this.auth_type = generatorConfig?.authType; if (toolRegistry) { @@ -135,6 +137,7 @@ export class StartSessionEvent implements BaseTelemetryEvent { mcp_tools: this.mcp_tools, mcp_tools_count: this.mcp_tools_count, output_format: this.output_format, + extensions: this.extensions, extensions_count: this.extensions_count, extension_ids: this.extension_ids, auth_type: this.auth_type,