Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sdk.logging] More consistent handling of StateValues/Attributes #4334

Merged
merged 22 commits into from Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 1 addition & 10 deletions docs/logs/redaction/MyRedactionProcessor.cs
Expand Up @@ -23,15 +23,6 @@ internal class MyRedactionProcessor : BaseProcessor<LogRecord>
{
public override void OnEnd(LogRecord logRecord)
{
if (logRecord.State == null)
{
// When State is null, OTel SDK guarantees StateValues is populated
// TODO: Debug.Assert?
logRecord.StateValues = new MyClassWithRedactionEnumerator(logRecord.StateValues);
}
else if (logRecord.State is IReadOnlyList<KeyValuePair<string, object>> listOfKvp)
{
logRecord.State = new MyClassWithRedactionEnumerator(listOfKvp);
}
logRecord.Attributes ??= new MyClassWithRedactionEnumerator(logRecord.Attributes);
CodeBlanch marked this conversation as resolved.
Show resolved Hide resolved
}
}
38 changes: 9 additions & 29 deletions src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs
Expand Up @@ -81,42 +81,22 @@ public override ExportResult Export(in Batch<LogRecord> batch)
this.WriteLine($"{"LogRecord.FormattedMessage:",-RightPaddingLength}{logRecord.FormattedMessage}");
}

if (logRecord.State != null)
if (logRecord.Body != null)
{
if (logRecord.State is IReadOnlyList<KeyValuePair<string, object>> listKvp)
{
this.WriteLine("LogRecord.State (Key:Value):");
for (int i = 0; i < listKvp.Count; i++)
{
// Special casing {OriginalFormat}
// See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182
// for explanation.
var valueToTransform = listKvp[i].Key.Equals("{OriginalFormat}")
? new KeyValuePair<string, object>("OriginalFormat (a.k.a Body)", listKvp[i].Value)
: listKvp[i];

if (ConsoleTagTransformer.Instance.TryTransformTag(valueToTransform, out var result))
{
this.WriteLine($"{string.Empty,-4}{result}");
}
}
}
else
{
this.WriteLine($"{"LogRecord.State:",-RightPaddingLength}{logRecord.State}");
}
this.WriteLine($"{"LogRecord.Body:",-RightPaddingLength}{logRecord.Body}");
}
else if (logRecord.StateValues != null)

if (logRecord.Attributes != null)
{
this.WriteLine("LogRecord.StateValues (Key:Value):");
for (int i = 0; i < logRecord.StateValues.Count; i++)
this.WriteLine("LogRecord.Attributes (Key:Value):");
for (int i = 0; i < logRecord.Attributes.Count; i++)
{
// Special casing {OriginalFormat}
// See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182
// for explanation.
var valueToTransform = logRecord.StateValues[i].Key.Equals("{OriginalFormat}")
? new KeyValuePair<string, object>("OriginalFormat (a.k.a Body)", logRecord.StateValues[i].Value)
: logRecord.StateValues[i];
var valueToTransform = logRecord.Attributes[i].Key.Equals("{OriginalFormat}")
? new KeyValuePair<string, object>("OriginalFormat (a.k.a Body)", logRecord.Attributes[i].Value)
: logRecord.Attributes[i];

if (ConsoleTagTransformer.Instance.TryTransformTag(valueToTransform, out var result))
{
Expand Down
Expand Up @@ -36,11 +36,6 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge
/// <summary>
/// Adds OTLP Exporter as a configuration to the OpenTelemetry ILoggingBuilder.
/// </summary>
/// <remarks>
/// Note: AddOtlpExporter automatically sets <see
/// cref="OpenTelemetryLoggerOptions.ParseStateValues"/> to <see
/// langword="true"/>.
/// </remarks>
/// <param name="loggerOptions"><see cref="OpenTelemetryLoggerOptions"/> options to use.</param>
/// <param name="configure">Callback action for configuring <see cref="OtlpExporterOptions"/>.</param>
/// <returns>The instance of <see cref="OpenTelemetryLoggerOptions"/> to chain the calls.</returns>
Expand All @@ -53,8 +48,6 @@ public static OpenTelemetryLoggerOptions AddOtlpExporter(this OpenTelemetryLogge
OpenTelemetryLoggerOptions loggerOptions,
Action<OtlpExporterOptions> configure)
{
loggerOptions.ParseStateValues = true;
cijothomas marked this conversation as resolved.
Show resolved Hide resolved

var exporterOptions = new OtlpExporterOptions();

// TODO: We are using span/activity batch environment variable keys
Expand Down
Expand Up @@ -113,18 +113,18 @@ internal static OtlpLogs.LogRecord ToOtlpLog(this LogRecord logRecord, SdkLimitO
bodyPopulatedFromFormattedMessage = true;
}

if (logRecord.StateValues != null)
if (logRecord.Attributes != null)
{
foreach (var stateValue in logRecord.StateValues)
foreach (var attribute in logRecord.Attributes)
{
// Special casing {OriginalFormat}
// See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182
// for explanation.
if (stateValue.Key.Equals("{OriginalFormat}") && !bodyPopulatedFromFormattedMessage)
if (attribute.Key.Equals("{OriginalFormat}") && !bodyPopulatedFromFormattedMessage)
{
otlpLogRecord.Body = new OtlpCommon.AnyValue { StringValue = stateValue.Value as string };
otlpLogRecord.Body = new OtlpCommon.AnyValue { StringValue = attribute.Value as string };
}
else if (OtlpKeyValueTransformer.Instance.TryTransformTag(stateValue, out var result, attributeValueLengthLimit))
else if (OtlpKeyValueTransformer.Instance.TryTransformTag(attribute, out var result, attributeValueLengthLimit))
{
otlpLogRecord.AddAttribute(result, attributeCountLimit);
}
Expand Down
8 changes: 8 additions & 0 deletions src/OpenTelemetry/.publicApi/net462/PublicAPI.Unshipped.txt
@@ -1,3 +1,11 @@
OpenTelemetry.Logs.LogRecord.Attributes.get -> System.Collections.Generic.IReadOnlyList<System.Collections.Generic.KeyValuePair<string!, object?>>?
OpenTelemetry.Logs.LogRecord.Attributes.set -> void
OpenTelemetry.Logs.LogRecord.Body.get -> string?
OpenTelemetry.Logs.LogRecord.Body.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.set -> void
OpenTelemetry.Metrics.AlwaysOffExemplarFilter
OpenTelemetry.Metrics.AlwaysOffExemplarFilter.AlwaysOffExemplarFilter() -> void
OpenTelemetry.Metrics.AlwaysOnExemplarFilter
Expand Down
8 changes: 8 additions & 0 deletions src/OpenTelemetry/.publicApi/net6.0/PublicAPI.Unshipped.txt
@@ -1,3 +1,11 @@
OpenTelemetry.Logs.LogRecord.Attributes.get -> System.Collections.Generic.IReadOnlyList<System.Collections.Generic.KeyValuePair<string!, object?>>?
OpenTelemetry.Logs.LogRecord.Attributes.set -> void
OpenTelemetry.Logs.LogRecord.Body.get -> string?
OpenTelemetry.Logs.LogRecord.Body.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.set -> void
OpenTelemetry.Metrics.AlwaysOffExemplarFilter
OpenTelemetry.Metrics.AlwaysOffExemplarFilter.AlwaysOffExemplarFilter() -> void
OpenTelemetry.Metrics.AlwaysOnExemplarFilter
Expand Down
@@ -1,3 +1,11 @@
OpenTelemetry.Logs.LogRecord.Attributes.get -> System.Collections.Generic.IReadOnlyList<System.Collections.Generic.KeyValuePair<string!, object?>>?
OpenTelemetry.Logs.LogRecord.Attributes.set -> void
OpenTelemetry.Logs.LogRecord.Body.get -> string?
OpenTelemetry.Logs.LogRecord.Body.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.set -> void
OpenTelemetry.Metrics.AlwaysOffExemplarFilter
OpenTelemetry.Metrics.AlwaysOffExemplarFilter.AlwaysOffExemplarFilter() -> void
OpenTelemetry.Metrics.AlwaysOnExemplarFilter
Expand Down
@@ -1,3 +1,11 @@
OpenTelemetry.Logs.LogRecord.Attributes.get -> System.Collections.Generic.IReadOnlyList<System.Collections.Generic.KeyValuePair<string!, object?>>?
OpenTelemetry.Logs.LogRecord.Attributes.set -> void
OpenTelemetry.Logs.LogRecord.Body.get -> string?
OpenTelemetry.Logs.LogRecord.Body.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeState.set -> void
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.get -> bool
OpenTelemetry.Logs.OpenTelemetryLoggerOptions.IncludeTraceState.set -> void
OpenTelemetry.Metrics.AlwaysOffExemplarFilter
OpenTelemetry.Metrics.AlwaysOffExemplarFilter.AlwaysOffExemplarFilter() -> void
OpenTelemetry.Metrics.AlwaysOnExemplarFilter
Expand Down
15 changes: 15 additions & 0 deletions src/OpenTelemetry/Internal/OpenTelemetrySdkEventSource.cs
Expand Up @@ -140,6 +140,15 @@ public void DroppedExportProcessorItems(string exportProcessorName, string expor
}
}

[NonEvent]
public void LoggerParseStateException<TState>(Exception exception)
{
if (this.IsEnabled(EventLevel.Warning, EventKeywords.All))
{
this.LoggerParseStateException(typeof(TState).FullName!, exception.ToInvariantString());
}
}

[Event(4, Message = "Unknown error in SpanProcessor event '{0}': '{1}'.", Level = EventLevel.Error)]
public void SpanProcessorException(string evnt, string ex)
{
Expand Down Expand Up @@ -284,6 +293,12 @@ public void InvalidEnvironmentVariable(string key, string? value)
this.WriteEvent(47, key, value);
}

[Event(48, Message = "Exception thrown parsing log state of type '{0}'. Exception: '{1}'", Level = EventLevel.Warning)]
public void LoggerParseStateException(string type, string error)
{
this.WriteEvent(48, type, error);
}

#if DEBUG
public class OpenTelemetryEventListener : EventListener
{
Expand Down