open-telemetry/opentelemetry-dotnet

Pooled objects in attibutes (working with Microsoft.Extensions.ComplianceRedaction)

Open

#5,276 opened on Jan 29, 2024

View on GitHub
 (24 comments) (2 reactions) (1 assignee)C# (889 forks)auto 404
bughelp wantedlogs

Repository metrics

Stars
 (3,725 stars)
PR merge metrics
 (PR metrics pending)

Description

Bug Report

Currently working on net8.0

    <PackageReference Include="Microsoft.Extensions.Compliance.Redaction" Version="8.1.0" />
    <PackageReference Include="Microsoft.Extensions.Telemetry" Version="8.1.0" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.7.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.7.0" />

Symptom

When using redaction and batch otlp protocol, redacted values are not stored.

What is the expected behavior?

Expected: the redacted value

What is the actual behavior?

Actual: no value store (the key is even not sent)

Reproduce

Little hard to reproduce as it needs a sink to send logs to. However, I've found the issue: when using redaction, the redacted values are stored as JustInTimeRedactor (see) to avoid allocations. When using batch exporter, as it might take time to send telemetry and as JustInTimeRedactor is pooled, the value can either not be available or reused by something else.

Additional Context

I've found a kind of workaround which is adding a Processor which "freezes" pooled values.

public class FreezePooledValuesProcessor : BaseProcessor<LogRecord>
{
    public override void OnStart(LogRecord data)
    {
        base.OnStart(data);
    }

    public override void OnEnd(LogRecord data)
    {
        if (data.Attributes is not null)
        {
            data.Attributes = data.Attributes
                .Select(kvp => kvp.Value is IResettable resettable ? KeyValuePair.Create<string, object?>(kvp.Key, resettable.ToString()) : kvp)
                .ToList();
        }

        base.OnEnd(data);
    }
}

Contributor guide