diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs index e907078d535..e4a347ded70 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/FunctionInvokingChatClient.cs @@ -1128,7 +1128,7 @@ FunctionResultContent CreateFunctionResultContent(FunctionInvocationResult resul startingTimestamp = Stopwatch.GetTimestamp(); if (_logger.IsEnabled(LogLevel.Trace)) { - LogInvokingSensitive(context.Function.Name, LoggingHelpers.AsJson(context.Arguments, context.Function.JsonSerializerOptions)); + LogInvokingSensitive(context.Function.Name, TelemetryHelpers.AsJson(context.Arguments, context.Function.JsonSerializerOptions)); } else { @@ -1169,7 +1169,7 @@ FunctionResultContent CreateFunctionResultContent(FunctionInvocationResult resul if (result is not null && _logger.IsEnabled(LogLevel.Trace)) { - LogInvocationCompletedSensitive(context.Function.Name, elapsed, LoggingHelpers.AsJson(result, context.Function.JsonSerializerOptions)); + LogInvocationCompletedSensitive(context.Function.Name, elapsed, TelemetryHelpers.AsJson(result, context.Function.JsonSerializerOptions)); } else { diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/LoggingChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/LoggingChatClient.cs index aec72eddcdc..c39fa2c0eb6 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/LoggingChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/LoggingChatClient.cs @@ -169,7 +169,7 @@ public override async IAsyncEnumerable GetStreamingResponseA } } - private string AsJson(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions); + private string AsJson(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions); [LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")] private partial void LogInvoked(string methodName); diff --git a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs index f9215060dea..d06ec3d3b5e 100644 --- a/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/ChatCompletion/OpenTelemetryChatClient.cs @@ -110,13 +110,16 @@ protected override void Dispose(bool disposing) /// /// if potentially sensitive information should be included in telemetry; /// if telemetry shouldn't include raw inputs and outputs. - /// The default value is . + /// The default value is , unless the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT + /// environment variable is set to "true" (case-insensitive). /// /// /// By default, telemetry includes metadata, such as token counts, but not raw inputs /// and outputs, such as message content, function call arguments, and function call results. + /// The default value can be overridden by setting the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT + /// environment variable to "true". Explicitly setting this property will override the environment variable. /// - public bool EnableSensitiveData { get; set; } + public bool EnableSensitiveData { get; set; } = TelemetryHelpers.EnableSensitiveDataDefault; /// public override object? GetService(Type serviceType, object? serviceKey = null) => diff --git a/src/Libraries/Microsoft.Extensions.AI/Embeddings/OpenTelemetryEmbeddingGenerator.cs b/src/Libraries/Microsoft.Extensions.AI/Embeddings/OpenTelemetryEmbeddingGenerator.cs index 402222feaa7..4b8f58ed7fb 100644 --- a/src/Libraries/Microsoft.Extensions.AI/Embeddings/OpenTelemetryEmbeddingGenerator.cs +++ b/src/Libraries/Microsoft.Extensions.AI/Embeddings/OpenTelemetryEmbeddingGenerator.cs @@ -89,13 +89,16 @@ public OpenTelemetryEmbeddingGenerator(IEmbeddingGenerator i /// /// if potentially sensitive information should be included in telemetry; /// if telemetry shouldn't include raw inputs and outputs. - /// The default value is . + /// The default value is , unless the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT + /// environment variable is set to "true" (case-insensitive). /// /// /// By default, telemetry includes metadata, such as token counts, but not raw inputs /// and outputs or additional options data. + /// The default value can be overridden by setting the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT + /// environment variable to "true". Explicitly setting this property will override the environment variable. /// - public bool EnableSensitiveData { get; set; } + public bool EnableSensitiveData { get; set; } = TelemetryHelpers.EnableSensitiveDataDefault; /// public override object? GetService(Type serviceType, object? serviceKey = null) => diff --git a/src/Libraries/Microsoft.Extensions.AI/Image/LoggingImageGenerator.cs b/src/Libraries/Microsoft.Extensions.AI/Image/LoggingImageGenerator.cs index 2eee33456c1..9ca0b8d06d2 100644 --- a/src/Libraries/Microsoft.Extensions.AI/Image/LoggingImageGenerator.cs +++ b/src/Libraries/Microsoft.Extensions.AI/Image/LoggingImageGenerator.cs @@ -102,7 +102,7 @@ public override async Task GenerateAsync( } } - private string AsJson(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions); + private string AsJson(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions); [LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")] private partial void LogInvoked(string methodName); diff --git a/src/Libraries/Microsoft.Extensions.AI/OpenTelemetryConsts.cs b/src/Libraries/Microsoft.Extensions.AI/OpenTelemetryConsts.cs index faf7c32e4cb..096b2091908 100644 --- a/src/Libraries/Microsoft.Extensions.AI/OpenTelemetryConsts.cs +++ b/src/Libraries/Microsoft.Extensions.AI/OpenTelemetryConsts.cs @@ -14,6 +14,9 @@ internal static class OpenTelemetryConsts public const string SecondsUnit = "s"; public const string TokensUnit = "token"; + /// Environment variable name for controlling whether sensitive content should be captured in telemetry by default. + public const string GenAICaptureMessageContentEnvVar = "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT"; + public const string ToolTypeFunction = "function"; public const string TypeText = "text"; diff --git a/src/Libraries/Microsoft.Extensions.AI/SpeechToText/LoggingSpeechToTextClient.cs b/src/Libraries/Microsoft.Extensions.AI/SpeechToText/LoggingSpeechToTextClient.cs index e7bf7850a94..10e499a7e57 100644 --- a/src/Libraries/Microsoft.Extensions.AI/SpeechToText/LoggingSpeechToTextClient.cs +++ b/src/Libraries/Microsoft.Extensions.AI/SpeechToText/LoggingSpeechToTextClient.cs @@ -179,7 +179,7 @@ public override async IAsyncEnumerable GetStreamingT } } - private string AsJson(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions); + private string AsJson(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions); [LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")] private partial void LogInvoked(string methodName); diff --git a/src/Libraries/Microsoft.Extensions.AI/LoggingHelpers.cs b/src/Libraries/Microsoft.Extensions.AI/TelemetryHelpers.cs similarity index 60% rename from src/Libraries/Microsoft.Extensions.AI/LoggingHelpers.cs rename to src/Libraries/Microsoft.Extensions.AI/TelemetryHelpers.cs index 72a7e283988..0468a93b26f 100644 --- a/src/Libraries/Microsoft.Extensions.AI/LoggingHelpers.cs +++ b/src/Libraries/Microsoft.Extensions.AI/TelemetryHelpers.cs @@ -4,14 +4,22 @@ #pragma warning disable CA1031 // Do not catch general exception types #pragma warning disable S108 // Nested blocks of code should not be left empty #pragma warning disable S2486 // Generic exceptions should not be ignored +#pragma warning disable SA1623 // Property summary documentation should match accessors +using System; using System.Text.Json; namespace Microsoft.Extensions.AI; -/// Provides internal helpers for implementing logging. -internal static class LoggingHelpers +/// Provides internal helpers for implementing telemetry. +internal static class TelemetryHelpers { + /// Gets a value the OpenTelemetry clients should use for their EnableSensitiveData property's default value. + /// Defaults to false. May be overridden by setting the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT environment variable to "true". + public static bool EnableSensitiveDataDefault { get; } = + Environment.GetEnvironmentVariable(OpenTelemetryConsts.GenAICaptureMessageContentEnvVar) is string envVar && + string.Equals(envVar, "true", StringComparison.OrdinalIgnoreCase); + /// Serializes as JSON for logging purposes. public static string AsJson(T value, JsonSerializerOptions? options) {