Telemetry: Improve clarity of user prompt event (#967)

This commit is contained in:
Jerop Kipruto 2025-06-11 21:43:00 -04:00 committed by GitHub
parent 1ef68e0612
commit 89f682f081
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 65 additions and 9 deletions

View File

@ -278,7 +278,7 @@ These are timestamped records of specific events.
- `gemini_cli.user_prompt`: Fired when a user submits a prompt.
- **Attributes**:
- `prompt_char_count`
- `prompt_length`
- `prompt` (except if `log_user_prompts_enabled` is false)
- `gemini_cli.tool_call`: Fired for every function call.

View File

@ -188,7 +188,7 @@ export const useGeminiStream = (
const trimmedQuery = query.trim();
logUserPrompt(config, {
prompt: trimmedQuery,
prompt_char_count: trimmedQuery.length,
prompt_length: trimmedQuery.length,
});
onDebugMessage(`User query: '${trimmedQuery}'`);
await logger?.logMessage(MessageSenderType.USER, trimmedQuery);

View File

@ -7,8 +7,12 @@
import { logs } from '@opentelemetry/api-logs';
import { SemanticAttributes } from '@opentelemetry/semantic-conventions';
import { Config } from '../config/config.js';
import { EVENT_API_RESPONSE } from './constants.js';
import { logApiResponse, logCliConfiguration } from './loggers.js';
import { EVENT_API_RESPONSE, EVENT_USER_PROMPT } from './constants.js';
import {
logApiResponse,
logCliConfiguration,
logUserPrompt,
} from './loggers.js';
import * as metrics from './metrics.js';
import * as sdk from './sdk.js';
import { vi, describe, beforeEach, it, expect } from 'vitest';
@ -86,6 +90,56 @@ describe('loggers', () => {
});
});
describe('logUserPrompt', () => {
const mockConfig = {
getSessionId: () => 'test-session-id',
getTelemetryLogUserPromptsEnabled: () => true,
} as unknown as Config;
it('should log a user prompt', () => {
const event = {
prompt: 'test-prompt',
prompt_length: 11,
};
logUserPrompt(mockConfig, event);
expect(mockLogger.emit).toHaveBeenCalledWith({
body: 'User prompt. Length: 11',
attributes: {
'session.id': 'test-session-id',
'event.name': EVENT_USER_PROMPT,
'event.timestamp': '2025-01-01T00:00:00.000Z',
prompt_length: 11,
prompt: 'test-prompt',
},
});
});
it('should not log prompt if disabled', () => {
const mockConfig = {
getSessionId: () => 'test-session-id',
getTelemetryLogUserPromptsEnabled: () => false,
} as unknown as Config;
const event = {
prompt: 'test-prompt',
prompt_length: 11,
};
logUserPrompt(mockConfig, event);
expect(mockLogger.emit).toHaveBeenCalledWith({
body: 'User prompt. Length: 11',
attributes: {
'session.id': 'test-session-id',
'event.name': EVENT_USER_PROMPT,
'event.timestamp': '2025-01-01T00:00:00.000Z',
prompt_length: 11,
},
});
});
});
describe('logApiResponse', () => {
const mockConfig = {
getSessionId: () => 'test-session-id',

View File

@ -81,19 +81,21 @@ export function logUserPrompt(
},
): void {
if (!isTelemetrySdkInitialized()) return;
const { prompt, ...restOfEventArgs } = event;
const attributes: LogAttributes = {
...getCommonAttributes(config),
...restOfEventArgs,
'event.name': EVENT_USER_PROMPT,
'event.timestamp': new Date().toISOString(),
prompt_length: event.prompt_length,
};
if (shouldLogUserPrompts(config)) {
attributes.prompt = prompt;
attributes.prompt = event.prompt;
}
const logger = logs.getLogger(SERVICE_NAME);
const logRecord: LogRecord = {
body: `User prompt. Length: ${event.prompt_char_count}`,
body: `User prompt. Length: ${event.prompt_length}`,
attributes,
};
logger.emit(logRecord);

View File

@ -7,7 +7,7 @@
export interface UserPromptEvent {
'event.name': 'user_prompt';
'event.timestamp': string; // ISO 8601
prompt_char_count: number;
prompt_length: number;
prompt?: string;
}