Logs the auth type in the user prompts, api responses and errors (#3795)

This commit is contained in:
uttamkanodia14 2025-07-11 22:17:46 +05:30 committed by GitHub
parent ed00612cf7
commit 93284281de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 65 additions and 4 deletions

View File

@ -154,6 +154,7 @@ Logs are timestamped records of specific events. The following events are logged
- **Attributes**: - **Attributes**:
- `prompt_length` - `prompt_length`
- `prompt` (this attribute is excluded if `log_prompts_enabled` is configured to be `false`) - `prompt` (this attribute is excluded if `log_prompts_enabled` is configured to be `false`)
- `auth_type`
- `gemini_cli.tool_call`: This event occurs for each function call. - `gemini_cli.tool_call`: This event occurs for each function call.
- **Attributes**: - **Attributes**:
@ -177,6 +178,7 @@ Logs are timestamped records of specific events. The following events are logged
- `error_type` - `error_type`
- `status_code` - `status_code`
- `duration_ms` - `duration_ms`
- `auth_type`
- `gemini_cli.api_response`: This event occurs upon receiving a response from Gemini API. - `gemini_cli.api_response`: This event occurs upon receiving a response from Gemini API.
- **Attributes**: - **Attributes**:
@ -190,6 +192,7 @@ Logs are timestamped records of specific events. The following events are logged
- `thoughts_token_count` - `thoughts_token_count`
- `tool_token_count` - `tool_token_count`
- `response_text` (if applicable) - `response_text` (if applicable)
- `auth_type`
### Metrics ### Metrics

View File

@ -212,6 +212,7 @@ export async function main() {
'event.timestamp': new Date().toISOString(), 'event.timestamp': new Date().toISOString(),
prompt: input, prompt: input,
prompt_id, prompt_id,
auth_type: config.getContentGeneratorConfig().authType!,
prompt_length: input.length, prompt_length: input.length,
}); });

View File

@ -273,6 +273,13 @@ describe('useGeminiStream', () => {
return clientInstance; return clientInstance;
}); });
const contentGeneratorConfig = {
model: 'test-model',
apiKey: 'test-key',
vertexai: false,
authType: AuthType.USE_GEMINI,
};
mockConfig = { mockConfig = {
apiKey: 'test-api-key', apiKey: 'test-api-key',
model: 'gemini-pro', model: 'gemini-pro',
@ -307,6 +314,9 @@ describe('useGeminiStream', () => {
}, },
setQuotaErrorOccurred: vi.fn(), setQuotaErrorOccurred: vi.fn(),
getQuotaErrorOccurred: vi.fn(() => false), getQuotaErrorOccurred: vi.fn(() => false),
getContentGeneratorConfig: vi
.fn()
.mockReturnValue(contentGeneratorConfig),
} as unknown as Config; } as unknown as Config;
mockOnDebugMessage = vi.fn(); mockOnDebugMessage = vi.fn();
mockHandleSlashCommand = vi.fn().mockResolvedValue(false); mockHandleSlashCommand = vi.fn().mockResolvedValue(false);

View File

@ -223,7 +223,12 @@ export const useGeminiStream = (
const trimmedQuery = query.trim(); const trimmedQuery = query.trim();
logUserPrompt( logUserPrompt(
config, config,
new UserPromptEvent(trimmedQuery.length, prompt_id, trimmedQuery), new UserPromptEvent(
trimmedQuery.length,
prompt_id,
config.getContentGeneratorConfig().authType!,
trimmedQuery,
),
); );
onDebugMessage(`User query: '${trimmedQuery}'`); onDebugMessage(`User query: '${trimmedQuery}'`);
await logger?.logMessage(MessageSenderType.USER, trimmedQuery); await logger?.logMessage(MessageSenderType.USER, trimmedQuery);

View File

@ -172,6 +172,7 @@ export class GeminiChat {
this.config.getModel(), this.config.getModel(),
durationMs, durationMs,
prompt_id, prompt_id,
this.config.getContentGeneratorConfig().authType!,
usageMetadata, usageMetadata,
responseText, responseText,
), ),
@ -193,6 +194,7 @@ export class GeminiChat {
errorMessage, errorMessage,
durationMs, durationMs,
prompt_id, prompt_id,
this.config.getContentGeneratorConfig().authType!,
errorType, errorType,
), ),
); );

View File

@ -266,6 +266,10 @@ export class ClearcutLogger {
gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID, gemini_cli_key: EventMetadataKey.GEMINI_CLI_PROMPT_ID,
value: JSON.stringify(event.prompt_id), value: JSON.stringify(event.prompt_id),
}, },
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
value: JSON.stringify(event.auth_type),
},
]; ];
this.enqueueLogEvent(this.createLogEvent(new_prompt_event_name, data)); this.enqueueLogEvent(this.createLogEvent(new_prompt_event_name, data));
@ -377,6 +381,10 @@ export class ClearcutLogger {
EventMetadataKey.GEMINI_CLI_API_RESPONSE_TOOL_TOKEN_COUNT, EventMetadataKey.GEMINI_CLI_API_RESPONSE_TOOL_TOKEN_COUNT,
value: JSON.stringify(event.tool_token_count), value: JSON.stringify(event.tool_token_count),
}, },
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
value: JSON.stringify(event.auth_type),
},
]; ];
this.enqueueLogEvent(this.createLogEvent(api_response_event_name, data)); this.enqueueLogEvent(this.createLogEvent(api_response_event_name, data));
@ -407,6 +415,10 @@ export class ClearcutLogger {
gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_DURATION_MS, gemini_cli_key: EventMetadataKey.GEMINI_CLI_API_ERROR_DURATION_MS,
value: JSON.stringify(event.duration_ms), value: JSON.stringify(event.duration_ms),
}, },
{
gemini_cli_key: EventMetadataKey.GEMINI_CLI_AUTH_TYPE,
value: JSON.stringify(event.auth_type),
},
]; ];
this.enqueueLogEvent(this.createLogEvent(api_error_event_name, data)); this.enqueueLogEvent(this.createLogEvent(api_error_event_name, data));

View File

@ -144,6 +144,9 @@ export enum EventMetadataKey {
// Logs the Prompt Id // Logs the Prompt Id
GEMINI_CLI_PROMPT_ID = 35, GEMINI_CLI_PROMPT_ID = 35,
// Logs the Auth type for the prompt, api responses and errors.
GEMINI_CLI_AUTH_TYPE = 36,
} }
export function getEventMetadataKey( export function getEventMetadataKey(

View File

@ -127,7 +127,12 @@ describe('loggers', () => {
} as unknown as Config; } as unknown as Config;
it('should log a user prompt', () => { it('should log a user prompt', () => {
const event = new UserPromptEvent(11, 'prompt-id-8', 'test-prompt'); const event = new UserPromptEvent(
11,
'prompt-id-8',
AuthType.USE_VERTEX_AI,
'test-prompt',
);
logUserPrompt(mockConfig, event); logUserPrompt(mockConfig, event);
@ -151,7 +156,11 @@ describe('loggers', () => {
getTargetDir: () => 'target-dir', getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true, getUsageStatisticsEnabled: () => true,
} as unknown as Config; } as unknown as Config;
const event = new UserPromptEvent(11, 'test-prompt'); const event = new UserPromptEvent(
11,
'test-prompt',
AuthType.CLOUD_SHELL,
);
logUserPrompt(mockConfig, event); logUserPrompt(mockConfig, event);
@ -202,6 +211,7 @@ describe('loggers', () => {
'test-model', 'test-model',
100, 100,
'prompt-id-1', 'prompt-id-1',
AuthType.LOGIN_WITH_GOOGLE,
usageData, usageData,
'test-response', 'test-response',
); );
@ -226,6 +236,7 @@ describe('loggers', () => {
total_token_count: 0, total_token_count: 0,
response_text: 'test-response', response_text: 'test-response',
prompt_id: 'prompt-id-1', prompt_id: 'prompt-id-1',
auth_type: 'oauth-personal',
}, },
}); });
@ -263,6 +274,7 @@ describe('loggers', () => {
'test-model', 'test-model',
100, 100,
'prompt-id-1', 'prompt-id-1',
AuthType.USE_GEMINI,
usageData, usageData,
'test-response', 'test-response',
'test-error', 'test-error',

View File

@ -96,13 +96,20 @@ export class UserPromptEvent {
'event.timestamp': string; // ISO 8601 'event.timestamp': string; // ISO 8601
prompt_length: number; prompt_length: number;
prompt_id: string; prompt_id: string;
auth_type: string;
prompt?: string; prompt?: string;
constructor(prompt_length: number, prompt_Id: string, prompt?: string) { constructor(
prompt_length: number,
prompt_Id: string,
auth_type: string,
prompt?: string,
) {
this['event.name'] = 'user_prompt'; this['event.name'] = 'user_prompt';
this['event.timestamp'] = new Date().toISOString(); this['event.timestamp'] = new Date().toISOString();
this.prompt_length = prompt_length; this.prompt_length = prompt_length;
this.prompt_id = prompt_Id; this.prompt_id = prompt_Id;
this.auth_type = auth_type;
this.prompt = prompt; this.prompt = prompt;
} }
} }
@ -160,12 +167,14 @@ export class ApiErrorEvent {
status_code?: number | string; status_code?: number | string;
duration_ms: number; duration_ms: number;
prompt_id: string; prompt_id: string;
auth_type: string;
constructor( constructor(
model: string, model: string,
error: string, error: string,
duration_ms: number, duration_ms: number,
prompt_id: string, prompt_id: string,
auth_type: string,
error_type?: string, error_type?: string,
status_code?: number | string, status_code?: number | string,
) { ) {
@ -177,6 +186,7 @@ export class ApiErrorEvent {
this.status_code = status_code; this.status_code = status_code;
this.duration_ms = duration_ms; this.duration_ms = duration_ms;
this.prompt_id = prompt_id; this.prompt_id = prompt_id;
this.auth_type = auth_type;
} }
} }
@ -195,11 +205,13 @@ export class ApiResponseEvent {
total_token_count: number; total_token_count: number;
response_text?: string; response_text?: string;
prompt_id: string; prompt_id: string;
auth_type: string;
constructor( constructor(
model: string, model: string,
duration_ms: number, duration_ms: number,
prompt_id: string, prompt_id: string,
auth_type: string,
usage_data?: GenerateContentResponseUsageMetadata, usage_data?: GenerateContentResponseUsageMetadata,
response_text?: string, response_text?: string,
error?: string, error?: string,
@ -218,6 +230,7 @@ export class ApiResponseEvent {
this.response_text = response_text; this.response_text = response_text;
this.error = error; this.error = error;
this.prompt_id = prompt_id; this.prompt_id = prompt_id;
this.auth_type = auth_type;
} }
} }