opentelemetry-dotnet
                                
                                 opentelemetry-dotnet copied to clipboard
                                
                                    opentelemetry-dotnet copied to clipboard
                            
                            
                            
                        [logs] Potential data loss when using custom log enrichment processor and upgrading to v1.5.0 - v1.7.0
[This issue is a meant as a landing spot for anyone searching.]
Issue: When upgrading to OpenTelemetry.dll v1.5.0 - v1.7.0 users may lose attributes added by custom LogRecord processors
Who is impacted?
Users attempting to enrich LogRecord instances via a BaseProcessor<LogRecord> implementation by setting only LogRecord.State. For example:
private sealed class LogEnrichmentProcessor : BaseProcessor<LogRecord>
{
    public override void OnEnd(LogRecord data)
    {
        if (data.State is IReadOnlyList<KeyValuePair<string, object?>> listOfKvp)
        {
            data.State = this.AddFields(listOfKvp);
        }
    }
    private IReadOnlyList<KeyValuePair<string, object?>> AddFields(IReadOnlyList<KeyValuePair<string, object?>> stateValues)
    {
        // Implementation not shown
    }
}
What happens?
Starting with OpenTelemetry v1.5.0 the SDK will automatically set Attributes \ StateValues if the logged TState implements IReadOnlyList or IEnumerable of KeyValuePair<string, object?>.
When the OnEnd code above executes, LogRecord.State & LogRecord.Attributes \ LogRecord.StateValues are in sync. But when it exits, they are out of sync.
Depending on the exporter(s) being used, data loss may occur:
- 
If an exporter looks at Attributes\StateValuesfirst, it will export the original (prior to enrichment) attributes and the enriched attributes will be lost.
- 
If an exporter looks at Statefirst, everything should work fine and the enriched data will be exported.
Is there a fix?
- 
Upgrade to an OpenTelemetry SDK >v1.7.0 which includes #5169 to keep State&Attributes\StateValuesin sync automatically.
- 
Or update the log processor to do this: public override void OnEnd(LogRecord data) { if (data.State is IReadOnlyList<KeyValuePair<string, object>> listOfKvp) { data.State = data.StateValues = this.AddFields(data, listOfKvp); } }Setting both StateandStateValues(orAttributes) will work for all known SDK versions.