Path: blob/main/extensions/copilot/src/platform/otel/common/test/agentOTelEnv.spec.ts
13406 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { describe, expect, it } from 'vitest';6import { deriveClaudeOTelEnv, deriveCopilotCliOTelEnv } from '../agentOTelEnv';7import type { OTelConfig } from '../otelConfig';89function makeConfig(overrides: Partial<OTelConfig> = {}): OTelConfig {10return {11enabled: true,12enabledExplicitly: true,13enabledVia: 'setting',14exporterType: 'otlp-http',15otlpEndpoint: 'http://localhost:4318',16otlpProtocol: 'http',17captureContent: false,18dbSpanExporter: false,19logLevel: 'info',20httpInstrumentation: false,21serviceName: 'copilot-chat',22serviceVersion: '1.0.0',23sessionId: 'test-session',24resourceAttributes: {},25...overrides,26};27}2829const emptyEnv: Record<string, string | undefined> = {};3031describe('deriveCopilotCliOTelEnv', () => {32it('returns empty when disabled', () => {33const result = deriveCopilotCliOTelEnv(makeConfig({ enabled: false }), emptyEnv);34expect(result).toEqual({});35});3637it('returns correct env vars when enabled', () => {38const result = deriveCopilotCliOTelEnv(makeConfig(), emptyEnv);39expect(result).toEqual({40COPILOT_OTEL_ENABLED: 'true',41OTEL_EXPORTER_OTLP_ENDPOINT: 'http://localhost:4318',42});43});4445it('includes capture content var when captureContent is true', () => {46const result = deriveCopilotCliOTelEnv(makeConfig({ captureContent: true }), emptyEnv);47expect(result['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT']).toBe('true');48});4950it('includes file exporter path when set', () => {51const result = deriveCopilotCliOTelEnv(makeConfig({ fileExporterPath: '/tmp/otel.jsonl', exporterType: 'file' }), emptyEnv);52expect(result['COPILOT_OTEL_FILE_EXPORTER_PATH']).toBe('/tmp/otel.jsonl');53expect(result['COPILOT_OTEL_EXPORTER_TYPE']).toBe('file');54});5556it('does not set exporter type for non-file exporters', () => {57const result = deriveCopilotCliOTelEnv(makeConfig({ exporterType: 'otlp-http' }), emptyEnv);58expect(result['COPILOT_OTEL_EXPORTER_TYPE']).toBeUndefined();59});6061it('does not overwrite existing env vars', () => {62const existingEnv: Record<string, string | undefined> = {63COPILOT_OTEL_ENABLED: 'false',64OTEL_EXPORTER_OTLP_ENDPOINT: 'http://custom:9999',65};66const result = deriveCopilotCliOTelEnv(makeConfig(), existingEnv);67expect(result['COPILOT_OTEL_ENABLED']).toBeUndefined();68expect(result['OTEL_EXPORTER_OTLP_ENDPOINT']).toBeUndefined();69});7071it('does not include capture content when captureContent is false', () => {72const result = deriveCopilotCliOTelEnv(makeConfig({ captureContent: false }), emptyEnv);73expect(result['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT']).toBeUndefined();74});75});7677describe('deriveClaudeOTelEnv', () => {78it('returns empty when disabled', () => {79const result = deriveClaudeOTelEnv(makeConfig({ enabled: false }), emptyEnv);80expect(result).toEqual({});81});8283it('returns correct env vars when enabled with HTTP', () => {84const result = deriveClaudeOTelEnv(makeConfig(), emptyEnv);85expect(result).toEqual({86CLAUDE_CODE_ENABLE_TELEMETRY: '1',87OTEL_METRICS_EXPORTER: 'otlp',88OTEL_LOGS_EXPORTER: 'otlp',89OTEL_EXPORTER_OTLP_ENDPOINT: 'http://localhost:4318',90OTEL_EXPORTER_OTLP_PROTOCOL: 'http/json',91});92});9394it('uses gRPC protocol when configured', () => {95const result = deriveClaudeOTelEnv(makeConfig({ otlpProtocol: 'grpc' }), emptyEnv);96expect(result['OTEL_EXPORTER_OTLP_PROTOCOL']).toBe('grpc');97});9899it('includes content capture vars when captureContent is true', () => {100const result = deriveClaudeOTelEnv(makeConfig({ captureContent: true }), emptyEnv);101expect(result['OTEL_LOG_USER_PROMPTS']).toBe('1');102expect(result['OTEL_LOG_TOOL_DETAILS']).toBe('1');103});104105it('does not include content capture vars when captureContent is false', () => {106const result = deriveClaudeOTelEnv(makeConfig({ captureContent: false }), emptyEnv);107expect(result['OTEL_LOG_USER_PROMPTS']).toBeUndefined();108expect(result['OTEL_LOG_TOOL_DETAILS']).toBeUndefined();109});110111it('does not overwrite existing env vars', () => {112const existingEnv: Record<string, string | undefined> = {113CLAUDE_CODE_ENABLE_TELEMETRY: '0',114OTEL_EXPORTER_OTLP_ENDPOINT: 'http://custom:9999',115OTEL_EXPORTER_OTLP_PROTOCOL: 'grpc',116};117const result = deriveClaudeOTelEnv(makeConfig(), existingEnv);118expect(result['CLAUDE_CODE_ENABLE_TELEMETRY']).toBeUndefined();119expect(result['OTEL_EXPORTER_OTLP_ENDPOINT']).toBeUndefined();120expect(result['OTEL_EXPORTER_OTLP_PROTOCOL']).toBeUndefined();121});122123it('does not include file exporter path (not supported by Claude SDK)', () => {124const result = deriveClaudeOTelEnv(makeConfig({ fileExporterPath: '/tmp/otel.jsonl' }), emptyEnv);125expect(result['COPILOT_OTEL_FILE_EXPORTER_PATH']).toBeUndefined();126});127});128129130