feat(telemetry): add flag for enabling traces specifically (#25343)

This commit is contained in:
Spencer
2026-04-21 14:07:32 -04:00
committed by GitHub
parent 7f8f3309a6
commit c260550146
25 changed files with 282 additions and 46 deletions
+1
View File
@@ -194,6 +194,7 @@ class DelegateInvocation extends BaseToolInvocation<
{
operation: GeminiCliOperation.AgentCall,
logPrompts: this.context.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.context.config.getTelemetryTracesEnabled(),
sessionId: this.context.config.getSessionId(),
attributes: {
[GEN_AI_AGENT_NAME]: this.definition.name,
+6
View File
@@ -205,6 +205,7 @@ export interface PlanSettings {
export interface TelemetrySettings {
enabled?: boolean;
traces?: boolean;
target?: TelemetryTarget;
otlpEndpoint?: string;
otlpProtocol?: 'grpc' | 'http';
@@ -1061,6 +1062,7 @@ export class Config implements McpContext, AgentLoopContext {
this.accessibility = params.accessibility ?? {};
this.telemetrySettings = {
enabled: params.telemetry?.enabled ?? false,
traces: params.telemetry?.traces ?? false,
target: params.telemetry?.target ?? DEFAULT_TELEMETRY_TARGET,
otlpEndpoint: params.telemetry?.otlpEndpoint ?? DEFAULT_OTLP_ENDPOINT,
otlpProtocol: params.telemetry?.otlpProtocol,
@@ -2732,6 +2734,10 @@ export class Config implements McpContext, AgentLoopContext {
return this.telemetrySettings.enabled ?? false;
}
getTelemetryTracesEnabled(): boolean {
return this.telemetrySettings.traces ?? false;
}
getTelemetryLogPromptsEnabled(): boolean {
return this.telemetrySettings.logPrompts ?? true;
}
@@ -153,6 +153,7 @@ describe('GeminiChat', () => {
promptId: 'test-session-id',
getSessionId: () => 'test-session-id',
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
getUsageStatisticsEnabled: () => true,
getDebugMode: () => false,
getContentGeneratorConfig: vi.fn().mockImplementation(() => ({
@@ -96,6 +96,7 @@ describe('GeminiChat Network Retries', () => {
promptId: 'test-session-id',
getSessionId: () => 'test-session-id',
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
getUsageStatisticsEnabled: () => true,
getDebugMode: () => false,
getContentGeneratorConfig: vi.fn().mockReturnValue({
@@ -73,6 +73,7 @@ describe('LoggingContentGenerator', () => {
authType: 'API_KEY',
}),
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(true),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
refreshUserQuotaIfStale: vi.fn().mockResolvedValue(undefined),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
} as unknown as Config;
@@ -361,6 +361,7 @@ export class LoggingContentGenerator implements ContentGenerator {
{
operation: GeminiCliOperation.LLMCall,
logPrompts: this.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.config.getTelemetryTracesEnabled(),
sessionId: this.config.getSessionId(),
attributes: {
[GEN_AI_REQUEST_MODEL]: req.model,
@@ -452,6 +453,7 @@ export class LoggingContentGenerator implements ContentGenerator {
{
operation: GeminiCliOperation.LLMCall,
logPrompts: this.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.config.getTelemetryTracesEnabled(),
sessionId: this.config.getSessionId(),
attributes: {
[GEN_AI_REQUEST_MODEL]: req.model,
@@ -607,6 +609,7 @@ export class LoggingContentGenerator implements ContentGenerator {
{
operation: GeminiCliOperation.LLMCall,
logPrompts: this.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.config.getTelemetryTracesEnabled(),
sessionId: this.config.getSessionId(),
attributes: {
[GEN_AI_REQUEST_MODEL]: req.model,
@@ -905,6 +905,7 @@ describe('Plan Mode Denial Consistency', () => {
getEnableHooks: vi.fn().mockReturnValue(false),
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.PLAN), // Key: Plan Mode
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
setApprovalMode: vi.fn(),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
getUsageStatisticsEnabled: vi.fn().mockReturnValue(false),
@@ -178,6 +178,7 @@ describe('Scheduler (Orchestrator)', () => {
setApprovalMode: vi.fn(),
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
} as unknown as Mocked<Config>;
@@ -1517,6 +1518,7 @@ describe('Scheduler MCP Progress', () => {
setApprovalMode: vi.fn(),
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
} as unknown as Mocked<Config>;
+1
View File
@@ -196,6 +196,7 @@ export class Scheduler {
{
operation: GeminiCliOperation.ScheduleToolCalls,
logPrompts: this.context.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.context.config.getTelemetryTracesEnabled(),
sessionId: this.context.config.getSessionId(),
},
async ({ metadata: spanMetadata }) => {
@@ -71,6 +71,7 @@ function createMockConfig(overrides: Partial<Config> = {}): Config {
getEnableHooks: () => true,
getExperiments: () => {},
getTelemetryLogPromptsEnabled: () => false,
getTelemetryTracesEnabled: () => false,
getPolicyEngine: () =>
({
check: async () => ({ decision: 'allow' }),
@@ -218,6 +218,7 @@ describe('Scheduler Parallel Execution', () => {
setApprovalMode: vi.fn(),
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(false),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
} as unknown as Mocked<Config>;
@@ -84,6 +84,7 @@ export class ToolExecutor {
{
operation: GeminiCliOperation.ToolCall,
logPrompts: this.config.getTelemetryLogPromptsEnabled(),
tracesEnabled: this.config.getTelemetryTracesEnabled(),
sessionId: this.config.getSessionId(),
attributes: {
[GEN_AI_TOOL_NAME]: toolName,
+5
View File
@@ -60,6 +60,10 @@ export async function resolveTelemetrySettings(options: {
parseBooleanEnvFlag(env['GEMINI_TELEMETRY_ENABLED']) ??
settings.enabled;
const traces =
parseBooleanEnvFlag(env['GEMINI_TELEMETRY_TRACES_ENABLED']) ??
settings.traces;
const rawTarget =
argv.telemetryTarget ??
env['GEMINI_TELEMETRY_TARGET'] ??
@@ -110,6 +114,7 @@ export async function resolveTelemetrySettings(options: {
return {
enabled,
traces,
target,
otlpEndpoint,
otlpProtocol,
@@ -37,6 +37,7 @@ describe('conseca-logger', () => {
getTelemetryEnabled: vi.fn().mockReturnValue(true),
getSessionId: vi.fn().mockReturnValue('test-session-id'),
getTelemetryLogPromptsEnabled: vi.fn().mockReturnValue(true),
getTelemetryTracesEnabled: vi.fn().mockReturnValue(false),
isInteractive: vi.fn().mockReturnValue(true),
getExperiments: vi.fn().mockReturnValue({ experimentIds: [] }),
getContentGeneratorConfig: vi.fn().mockReturnValue({ authType: 'oauth' }),
+115 -5
View File
@@ -216,6 +216,7 @@ describe('loggers', () => {
getTelemetryEnabled: () => true,
getUsageStatisticsEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
getFileFilteringRespectGitIgnore: () => true,
getFileFilteringAllowBuildArtifacts: () => false,
getDebugMode: () => true,
@@ -313,6 +314,7 @@ describe('loggers', () => {
getSessionId: () => 'test-session-id',
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
getUsageStatisticsEnabled: () => true,
isInteractive: () => false,
getExperiments: () => undefined,
@@ -352,6 +354,7 @@ describe('loggers', () => {
getSessionId: () => 'test-session-id',
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => false,
getTelemetryTracesEnabled: () => false,
getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true,
isInteractive: () => false,
@@ -392,6 +395,7 @@ describe('loggers', () => {
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => true,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -493,10 +497,10 @@ describe('loggers', () => {
'gen_ai.output.messages':
'[{"finish_reason":"stop","role":"system","parts":[{"type":"text","content":"candidate 1"}]}]',
'gen_ai.response.finish_reasons': ['stop'],
'gen_ai.operation.name': 'generate_content',
'gen_ai.response.model': 'test-model',
'gen_ai.usage.input_tokens': 17,
'gen_ai.usage.output_tokens': 50,
'gen_ai.operation.name': 'generate_content',
'gen_ai.output.type': 'text',
'gen_ai.request.choice.count': 1,
'gen_ai.request.seed': 678,
@@ -564,6 +568,57 @@ describe('loggers', () => {
});
});
it('should not log input and output messages when traces are disabled', () => {
const mockConfigNoTraces = {
getSessionId: () => 'test-session-id',
getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false, // Disabled
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
getContentGeneratorConfig: () => undefined,
} as unknown as Config;
const event = new ApiResponseEvent(
'test-model',
100,
{ prompt_id: 'prompt-id-1', contents: [] },
{ candidates: [] },
AuthType.LOGIN_WITH_GOOGLE,
undefined,
'test-response',
);
logApiResponse(mockConfigNoTraces, event);
expect(mockLogger.emit).toHaveBeenCalledWith(
expect.objectContaining({
body: 'GenAI operation details from test-model. Status: 200. Duration: 100ms.',
attributes: expect.objectContaining({
'event.name': 'gen_ai.client.inference.operation.details',
'gen_ai.operation.name': 'generate_content',
}),
}),
);
const emitCalls = mockLogger.emit.mock.calls;
const detailsCall = emitCalls.find(
(call) =>
call[0].attributes &&
call[0].attributes['event.name'] ===
'gen_ai.client.inference.operation.details',
);
expect(
detailsCall![0].attributes['gen_ai.input.messages'],
).toBeUndefined();
expect(
detailsCall![0].attributes['gen_ai.output.messages'],
).toBeUndefined();
});
it('should log an API response with a role', () => {
const event = new ApiResponseEvent(
'test-model',
@@ -596,6 +651,7 @@ describe('loggers', () => {
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => true,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -674,8 +730,6 @@ describe('loggers', () => {
'gen_ai.request.temperature': 1,
'gen_ai.request.top_p': 2,
'gen_ai.request.top_k': 3,
'gen_ai.input.messages':
'[{"role":"user","parts":[{"type":"text","content":"Hello"}]}]',
'gen_ai.operation.name': 'generate_content',
'gen_ai.output.type': 'text',
'gen_ai.request.choice.count': 1,
@@ -683,6 +737,8 @@ describe('loggers', () => {
'gen_ai.request.frequency_penalty': 10,
'gen_ai.request.presence_penalty': 6,
'gen_ai.request.max_tokens': 8000,
'gen_ai.input.messages':
'[{"role":"user","parts":[{"type":"text","content":"Hello"}]}]',
'server.address': 'foo.com',
'server.port': 8080,
'gen_ai.request.stop_sequences': ['stop', 'please stop'],
@@ -724,6 +780,52 @@ describe('loggers', () => {
});
});
it('should not log input messages when traces are disabled', () => {
const mockConfigNoTraces = {
getSessionId: () => 'test-session-id',
getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false, // Disabled
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
getContentGeneratorConfig: () => undefined,
} as unknown as Config;
const event = new ApiErrorEvent(
'test-model',
'error',
100,
{ prompt_id: 'prompt-id-1', contents: [] },
AuthType.LOGIN_WITH_GOOGLE,
'ApiError',
500,
);
logApiError(mockConfigNoTraces, event);
expect(mockLogger.emit).toHaveBeenCalledWith(
expect.objectContaining({
attributes: expect.objectContaining({
'event.name': 'gen_ai.client.inference.operation.details',
}),
}),
);
const emitCalls = mockLogger.emit.mock.calls;
const detailsCall = emitCalls.find(
(call) =>
call[0].attributes &&
call[0].attributes['event.name'] ===
'gen_ai.client.inference.operation.details',
);
expect(
detailsCall![0].attributes['gen_ai.input.messages'],
).toBeUndefined();
});
it('should log an API error with a role', () => {
const event = new ApiErrorEvent(
'test-model',
@@ -756,6 +858,7 @@ describe('loggers', () => {
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -833,7 +936,8 @@ describe('loggers', () => {
getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true, // Enabled
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => true, // Enabled
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -922,7 +1026,8 @@ describe('loggers', () => {
getTargetDir: () => 'target-dir',
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => false, // Disabled
getTelemetryLogPromptsEnabled: () => false,
getTelemetryTracesEnabled: () => false, // Disabled
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -978,6 +1083,7 @@ describe('loggers', () => {
getSessionId: () => 'test-session-id',
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -1140,6 +1246,7 @@ describe('loggers', () => {
getCoreTools: () => ['ls', 'read-file'],
getApprovalMode: () => 'default',
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
getFileFilteringRespectGitIgnore: () => true,
getFileFilteringAllowBuildArtifacts: () => false,
getDebugMode: () => true,
@@ -1170,6 +1277,7 @@ describe('loggers', () => {
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -1829,6 +1937,7 @@ describe('loggers', () => {
getUsageStatisticsEnabled: () => true,
getTelemetryEnabled: () => true,
getTelemetryLogPromptsEnabled: () => true,
getTelemetryTracesEnabled: () => false,
isInteractive: () => false,
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
@@ -2423,6 +2532,7 @@ describe('loggers', () => {
getExperiments: () => undefined,
getExperimentsAsync: async () => undefined,
getTelemetryLogPromptsEnabled: () => false,
getTelemetryTracesEnabled: () => false,
getContentGeneratorConfig: () => undefined,
} as unknown as Config;
+50 -10
View File
@@ -115,7 +115,11 @@ describe('runInDevTraceSpan', () => {
const fn = vi.fn(async () => 'result');
const result = await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
fn,
);
@@ -123,14 +127,22 @@ describe('runInDevTraceSpan', () => {
expect(trace.getTracer).toHaveBeenCalled();
expect(mockTracer.startActiveSpan).toHaveBeenCalledWith(
GeminiCliOperation.LLMCall,
{},
{
attributes: {
[GEN_AI_CONVERSATION_ID]: 'test-session-id',
},
},
expect.any(Function),
);
});
it('should set default attributes on the span metadata', async () => {
await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async ({ metadata }) => {
expect(metadata.attributes[GEN_AI_OPERATION_NAME]).toBe(
GeminiCliOperation.LLMCall,
@@ -148,7 +160,11 @@ describe('runInDevTraceSpan', () => {
it('should set span attributes from metadata on completion', async () => {
await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async ({ metadata }) => {
metadata.input = { query: 'hello' };
metadata.output = { response: 'world' };
@@ -175,7 +191,11 @@ describe('runInDevTraceSpan', () => {
const error = new Error('test error');
await expect(
runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async () => {
throw error;
},
@@ -197,7 +217,11 @@ describe('runInDevTraceSpan', () => {
}
const resultStream = await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async () => testStream(),
);
@@ -219,7 +243,11 @@ describe('runInDevTraceSpan', () => {
}
const resultStream = await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async () => testStream(),
);
@@ -233,7 +261,11 @@ describe('runInDevTraceSpan', () => {
}
const resultStream = await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async () => testStream(),
);
@@ -259,7 +291,11 @@ describe('runInDevTraceSpan', () => {
}
const resultStream = await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async () => errorStream(),
);
@@ -278,7 +314,11 @@ describe('runInDevTraceSpan', () => {
});
await runInDevTraceSpan(
{ operation: GeminiCliOperation.LLMCall, sessionId: 'test-session-id' },
{
operation: GeminiCliOperation.LLMCall,
sessionId: 'test-session-id',
tracesEnabled: true,
},
async ({ metadata }) => {
metadata.input = 'trigger error';
},
+38 -14
View File
@@ -125,10 +125,17 @@ export async function runInDevTraceSpan<R>(
operation: GeminiCliOperation;
logPrompts?: boolean;
sessionId: string;
tracesEnabled?: boolean;
},
fn: ({ metadata }: { metadata: SpanMetadata }) => Promise<R>,
): Promise<R> {
const { operation, logPrompts, sessionId, ...restOfSpanOpts } = opts;
const { operation, logPrompts, sessionId, tracesEnabled, ...restOfSpanOpts } =
opts;
restOfSpanOpts.attributes = {
...restOfSpanOpts.attributes,
[GEN_AI_CONVERSATION_ID]: sessionId,
};
const tracer = trace.getTracer(TRACER_NAME, TRACER_VERSION);
return tracer.startActiveSpan(operation, restOfSpanOpts, async (span) => {
@@ -148,24 +155,41 @@ export async function runInDevTraceSpan<R>(
}
spanEnded = true;
try {
if (logPrompts !== false) {
if (meta.input !== undefined) {
const truncated = truncateForTelemetry(meta.input);
if (truncated !== undefined) {
span.setAttribute(GEN_AI_INPUT_MESSAGES, truncated);
if (tracesEnabled) {
if (logPrompts !== false) {
if (meta.input !== undefined) {
const truncated = truncateForTelemetry(meta.input);
if (truncated !== undefined) {
span.setAttribute(GEN_AI_INPUT_MESSAGES, truncated);
}
}
if (meta.output !== undefined) {
const truncated = truncateForTelemetry(meta.output);
if (truncated !== undefined) {
span.setAttribute(GEN_AI_OUTPUT_MESSAGES, truncated);
}
}
}
if (meta.output !== undefined) {
const truncated = truncateForTelemetry(meta.output);
for (const [key, value] of Object.entries(meta.attributes)) {
const truncated = truncateForTelemetry(value);
if (truncated !== undefined) {
span.setAttribute(GEN_AI_OUTPUT_MESSAGES, truncated);
span.setAttribute(key, truncated);
}
}
}
for (const [key, value] of Object.entries(meta.attributes)) {
const truncated = truncateForTelemetry(value);
if (truncated !== undefined) {
span.setAttribute(key, truncated);
} else {
// Add basic attributes even when traces are disabled
for (const [key, value] of Object.entries(meta.attributes)) {
if (
key === GEN_AI_OPERATION_NAME ||
key === GEN_AI_AGENT_NAME ||
key === GEN_AI_AGENT_DESCRIPTION ||
key === GEN_AI_CONVERSATION_ID
) {
const truncated = truncateForTelemetry(value);
if (truncated !== undefined) {
span.setAttribute(key, truncated);
}
}
}
}
if (meta.error) {
+17 -6
View File
@@ -387,6 +387,13 @@ export class ToolCallEvent implements BaseTelemetryEvent {
}
export const EVENT_API_REQUEST = 'gemini_cli.api_request';
function shouldIncludePayloads(config: Config): boolean {
return (
config.getTelemetryTracesEnabled() && config.getTelemetryLogPromptsEnabled()
);
}
export class ApiRequestEvent implements BaseTelemetryEvent {
'event.name': 'api_request';
'event.timestamp': string;
@@ -443,7 +450,7 @@ export class ApiRequestEvent implements BaseTelemetryEvent {
attributes['server.port'] = this.prompt.server.port;
}
if (config.getTelemetryLogPromptsEnabled() && this.prompt.contents) {
if (shouldIncludePayloads(config) && this.prompt.contents) {
attributes['gen_ai.input.messages'] = JSON.stringify(
toInputMessages(this.prompt.contents),
);
@@ -540,7 +547,7 @@ export class ApiErrorEvent implements BaseTelemetryEvent {
attributes['server.port'] = this.prompt.server.port;
}
if (config.getTelemetryLogPromptsEnabled() && this.prompt.contents) {
if (shouldIncludePayloads(config) && this.prompt.contents) {
attributes['gen_ai.input.messages'] = JSON.stringify(
toInputMessages(this.prompt.contents),
);
@@ -707,9 +714,13 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
'event.timestamp': this['event.timestamp'],
'gen_ai.response.id': this.response.response_id,
'gen_ai.response.finish_reasons': this.finish_reasons,
'gen_ai.output.messages': JSON.stringify(
toOutputMessages(this.response.candidates),
),
...(shouldIncludePayloads(config)
? {
'gen_ai.output.messages': JSON.stringify(
toOutputMessages(this.response.candidates),
),
}
: {}),
...toGenerateContentConfigAttributes(this.prompt.generate_content_config),
...getConventionAttributes(this),
};
@@ -719,7 +730,7 @@ export class ApiResponseEvent implements BaseTelemetryEvent {
attributes['server.port'] = this.prompt.server.port;
}
if (config.getTelemetryLogPromptsEnabled() && this.prompt.contents) {
if (shouldIncludePayloads(config) && this.prompt.contents) {
attributes['gen_ai.input.messages'] = JSON.stringify(
toInputMessages(this.prompt.contents),
);