Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public override async IAsyncEnumerable<ChatResponseUpdate> GetStreamingResponseA
}
}

private string AsJson<T>(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions);
private string AsJson<T>(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions);

[LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")]
private partial void LogInvoked(string methodName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,16 @@ protected override void Dispose(bool disposing)
/// <value>
/// <see langword="true"/> if potentially sensitive information should be included in telemetry;
/// <see langword="false"/> if telemetry shouldn't include raw inputs and outputs.
/// The default value is <see langword="false"/>.
/// The default value is <see langword="false"/>, unless the <c>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT</c>
/// environment variable is set to "true" (case-insensitive).
/// </value>
/// <remarks>
/// 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 <c>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT</c>
/// environment variable to "true". Explicitly setting this property will override the environment variable.
/// </remarks>
public bool EnableSensitiveData { get; set; }
public bool EnableSensitiveData { get; set; } = TelemetryHelpers.EnableSensitiveDataDefault;

/// <inheritdoc/>
public override object? GetService(Type serviceType, object? serviceKey = null) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ public OpenTelemetryEmbeddingGenerator(IEmbeddingGenerator<TInput, TEmbedding> i
/// <value>
/// <see langword="true"/> if potentially sensitive information should be included in telemetry;
/// <see langword="false"/> if telemetry shouldn't include raw inputs and outputs.
/// The default value is <see langword="false"/>.
/// The default value is <see langword="false"/>, unless the <c>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT</c>
/// environment variable is set to "true" (case-insensitive).
/// </value>
/// <remarks>
/// 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 <c>OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT</c>
/// environment variable to "true". Explicitly setting this property will override the environment variable.
/// </remarks>
public bool EnableSensitiveData { get; set; }
public bool EnableSensitiveData { get; set; } = TelemetryHelpers.EnableSensitiveDataDefault;

/// <inheritdoc/>
public override object? GetService(Type serviceType, object? serviceKey = null) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public override async Task<ImageGenerationResponse> GenerateAsync(
}
}

private string AsJson<T>(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions);
private string AsJson<T>(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions);

[LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")]
private partial void LogInvoked(string methodName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ internal static class OpenTelemetryConsts
public const string SecondsUnit = "s";
public const string TokensUnit = "token";

/// <summary>Environment variable name for controlling whether sensitive content should be captured in telemetry by default.</summary>
public const string GenAICaptureMessageContentEnvVar = "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT";

public const string ToolTypeFunction = "function";

public const string TypeText = "text";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ public override async IAsyncEnumerable<SpeechToTextResponseUpdate> GetStreamingT
}
}

private string AsJson<T>(T value) => LoggingHelpers.AsJson(value, _jsonSerializerOptions);
private string AsJson<T>(T value) => TelemetryHelpers.AsJson(value, _jsonSerializerOptions);

[LoggerMessage(LogLevel.Debug, "{MethodName} invoked.")]
private partial void LogInvoked(string methodName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/// <summary>Provides internal helpers for implementing logging.</summary>
internal static class LoggingHelpers
/// <summary>Provides internal helpers for implementing telemetry.</summary>
internal static class TelemetryHelpers
{
/// <summary>Gets a value the OpenTelemetry clients should use for their EnableSensitiveData property's default value.</summary>
/// <remarks>Defaults to false. May be overridden by setting the OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT environment variable to "true".</remarks>
public static bool EnableSensitiveDataDefault { get; } =
Environment.GetEnvironmentVariable(OpenTelemetryConsts.GenAICaptureMessageContentEnvVar) is string envVar &&
string.Equals(envVar, "true", StringComparison.OrdinalIgnoreCase);

/// <summary>Serializes <paramref name="value"/> as JSON for logging purposes.</summary>
public static string AsJson<T>(T value, JsonSerializerOptions? options)
{
Expand Down
Loading