diff options
| author | Shreya Keshive <[email protected]> | 2025-07-29 16:20:37 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-29 20:20:37 +0000 |
| commit | 293bb820193a41aee6f1421367a2d1fc6d836422 (patch) | |
| tree | 639f1cb516ea4f0dd772a0a54a20790f5a63520c /packages/core/src | |
| parent | 80079cd2a5741d7024c8500853fe7a3af5e6ba0a (diff) | |
Adds centralized support to log slash commands + sub commands (#5128)
Diffstat (limited to 'packages/core/src')
| -rw-r--r-- | packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts | 21 | ||||
| -rw-r--r-- | packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts | 10 | ||||
| -rw-r--r-- | packages/core/src/telemetry/constants.ts | 1 | ||||
| -rw-r--r-- | packages/core/src/telemetry/index.ts | 2 | ||||
| -rw-r--r-- | packages/core/src/telemetry/loggers.ts | 23 | ||||
| -rw-r--r-- | packages/core/src/telemetry/types.ts | 17 |
6 files changed, 73 insertions, 1 deletions
diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts index fd5a9ab2..d221ef5e 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts @@ -19,6 +19,7 @@ import { FlashFallbackEvent, LoopDetectedEvent, FlashDecidedToContinueEvent, + SlashCommandEvent, } from '../types.js'; import { EventMetadataKey } from './event-metadata-key.js'; import { Config } from '../../config/config.js'; @@ -40,6 +41,7 @@ const end_session_event_name = 'end_session'; const flash_fallback_event_name = 'flash_fallback'; const loop_detected_event_name = 'loop_detected'; const flash_decided_to_continue_event_name = 'flash_decided_to_continue'; +const slash_command_event_name = 'slash_command'; export interface LogResponse { nextRequestWaitMs?: number; @@ -528,6 +530,25 @@ export class ClearcutLogger { this.flushIfNeeded(); } + logSlashCommandEvent(event: SlashCommandEvent): void { + const data = [ + { + gemini_cli_key: EventMetadataKey.GEMINI_CLI_SLASH_COMMAND_NAME, + value: JSON.stringify(event.command), + }, + ]; + + if (event.subcommand) { + data.push({ + gemini_cli_key: EventMetadataKey.GEMINI_CLI_SLASH_COMMAND_SUBCOMMAND, + value: JSON.stringify(event.subcommand), + }); + } + + this.enqueueLogEvent(this.createLogEvent(slash_command_event_name, data)); + this.flushIfNeeded(); + } + logEndSessionEvent(event: EndSessionEvent): void { const data = [ { diff --git a/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts b/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts index b34cc6ea..9a182f67 100644 --- a/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts +++ b/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts @@ -163,6 +163,16 @@ export enum EventMetadataKey { // Logs the type of loop detected. GEMINI_CLI_LOOP_DETECTED_TYPE = 38, + + // ========================================================================== + // Slash Command Event Keys + // =========================================================================== + + // Logs the name of the slash command. + GEMINI_CLI_SLASH_COMMAND_NAME = 41, + + // Logs the subcommand of the slash command. + GEMINI_CLI_SLASH_COMMAND_SUBCOMMAND = 42, } export function getEventMetadataKey( diff --git a/packages/core/src/telemetry/constants.ts b/packages/core/src/telemetry/constants.ts index 316e827f..42572228 100644 --- a/packages/core/src/telemetry/constants.ts +++ b/packages/core/src/telemetry/constants.ts @@ -15,6 +15,7 @@ export const EVENT_CLI_CONFIG = 'gemini_cli.config'; export const EVENT_FLASH_FALLBACK = 'gemini_cli.flash_fallback'; export const EVENT_FLASH_DECIDED_TO_CONTINUE = 'gemini_cli.flash_decided_to_continue'; +export const EVENT_SLASH_COMMAND = 'gemini_cli.slash_command'; export const METRIC_TOOL_CALL_COUNT = 'gemini_cli.tool.call.count'; export const METRIC_TOOL_CALL_LATENCY = 'gemini_cli.tool.call.latency'; diff --git a/packages/core/src/telemetry/index.ts b/packages/core/src/telemetry/index.ts index 8da31727..6648b229 100644 --- a/packages/core/src/telemetry/index.ts +++ b/packages/core/src/telemetry/index.ts @@ -26,6 +26,7 @@ export { logApiError, logApiResponse, logFlashFallback, + logSlashCommand, } from './loggers.js'; export { StartSessionEvent, @@ -37,6 +38,7 @@ export { ApiResponseEvent, TelemetryEvent, FlashFallbackEvent, + SlashCommandEvent, } from './types.js'; export { SpanStatusCode, ValueType } from '@opentelemetry/api'; export { SemanticAttributes } from '@opentelemetry/semantic-conventions'; diff --git a/packages/core/src/telemetry/loggers.ts b/packages/core/src/telemetry/loggers.ts index 073124f4..3ee806bb 100644 --- a/packages/core/src/telemetry/loggers.ts +++ b/packages/core/src/telemetry/loggers.ts @@ -17,6 +17,7 @@ import { EVENT_FLASH_FALLBACK, EVENT_FLASH_DECIDED_TO_CONTINUE, SERVICE_NAME, + EVENT_SLASH_COMMAND, } from './constants.js'; import { ApiErrorEvent, @@ -28,6 +29,7 @@ import { FlashFallbackEvent, FlashDecidedToContinueEvent, LoopDetectedEvent, + SlashCommandEvent, } from './types.js'; import { recordApiErrorMetrics, @@ -332,3 +334,24 @@ export function logFlashDecidedToContinue( }; logger.emit(logRecord); } + +export function logSlashCommand( + config: Config, + event: SlashCommandEvent, +): void { + ClearcutLogger.getInstance(config)?.logSlashCommandEvent(event); + if (!isTelemetrySdkInitialized()) return; + + const attributes: LogAttributes = { + ...getCommonAttributes(config), + ...event, + 'event.name': EVENT_SLASH_COMMAND, + }; + + const logger = logs.getLogger(SERVICE_NAME); + const logRecord: LogRecord = { + body: `Slash command: ${event.command}.`, + attributes, + }; + logger.emit(logRecord); +} diff --git a/packages/core/src/telemetry/types.ts b/packages/core/src/telemetry/types.ts index 69dffb08..d29b97d2 100644 --- a/packages/core/src/telemetry/types.ts +++ b/packages/core/src/telemetry/types.ts @@ -278,6 +278,20 @@ export class FlashDecidedToContinueEvent { } } +export class SlashCommandEvent { + 'event.name': 'slash_command'; + 'event.timestamp': string; // ISO 8106 + command: string; + subcommand?: string; + + constructor(command: string, subcommand?: string) { + this['event.name'] = 'slash_command'; + this['event.timestamp'] = new Date().toISOString(); + this.command = command; + this.subcommand = subcommand; + } +} + export type TelemetryEvent = | StartSessionEvent | EndSessionEvent @@ -288,4 +302,5 @@ export type TelemetryEvent = | ApiResponseEvent | FlashFallbackEvent | LoopDetectedEvent - | FlashDecidedToContinueEvent; + | FlashDecidedToContinueEvent + | SlashCommandEvent; |
