Comments (11)
Unless I'm missing something, I don't see how the BufferLogAttributes() method can prevent the issue.
I've read the associated issue mentioned in the method comment but we are not in the same case.
In 2905, the AttributesData
property needed to be enumerated and copied because it was of type HostingRequestStartingLog
and the enumeration need to be sync. However all the object in the KeyValuePair<string,object>
are objects which does not have lifetime scope. Most of them are just good ol' primitive types.
Here the difference is that it is the Value property of KeyValuePair<string,object>
which is scoped and the method don't freeze or copy its state.
Something like this would prevent the issue instead:
private void BufferLogAttributes()
{
var attributes = this.AttributeData;
if (attributes == null || attributes == this.AttributeStorage)
{
return;
}
var attributeStorage = this.AttributeStorage ??= new List<KeyValuePair<string, object?>>(attributes.Count);
foreach(var (key, value) in attributes)
{
if(value is IDisposable || value is IResettable)
{
value = value.ToString();
}
attributeStorage.Add(KeyValuePair<string,object?>.Create(key, value));
}
this.AttributeData = attributeStorage;
}
from opentelemetry-dotnet.
Thanks!
I have re-added bug label, will reachout to @CodeBlanch to comment further.
from opentelemetry-dotnet.
My employer has some logging code that creates logging-specific wrappers for application-specific objects. These objects have limited lifetime and are not safe to access across threads. The wrappers exist to provide ToString() for logs but skip all string formatting if ToString() is not called. These wrappers do not implement IDisposable, because they just reference the application-specific objects rather than own those; and they do not implement Microsoft.Extensions.ObjectPool.IResettable, because they antedate .NET 8.0.
from opentelemetry-dotnet.
You can use a OTEL Collector and OTLP Exporter to show the repro. You may use this example app - https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/examples/Console/TestOtlpExporter.cs#L16
The SDK's ILogger integration is expected to copy all attributes in the sync path itself, so if this is not working, it is likely a bug. But need to see a minimal repro to confirm.
from opentelemetry-dotnet.
Here's a repro:
https://github.com/NatMarchand/repro-dotnet-log-redactor/blob/main/ConsoleApp1/Program.cs
On my computer, I often (not every time) get a NullReferenceException
in Microsoft.Extensions.Telemetry.dll!Microsoft.Extensions.Logging.JustInTimeRedactor.ToString
as the inner _redactor is null because the JustInTimeRedactor is reset when it gets back to the pool.
The issue is on a separated thread OpenTelemetry-BatchExportProcessor-OtlpLogExporter
and the stack trace is the following:
Microsoft.Extensions.Telemetry.dll!Microsoft.Extensions.Logging.JustInTimeRedactor.ToString(string format, System.IFormatProvider formatProvider) Line 53
Microsoft.Extensions.Telemetry.dll!Microsoft.Extensions.Logging.JustInTimeRedactor.ToString() Line 45
OpenTelemetry.Exporter.OpenTelemetryProtocol.dll!OpenTelemetry.Internal.TagTransformer<OpenTelemetry.Proto.Common.V1.KeyValue>.TryTransformTag(System.Collections.Generic.KeyValuePair<string, object> tag, out OpenTelemetry.Proto.Common.V1.KeyValue result, int? maxLength) Line 73
OpenTelemetry.Exporter.OpenTelemetryProtocol.dll!OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.OtlpLogRecordTransformer.ToOtlpLog(OpenTelemetry.Logs.LogRecord logRecord) Line 152
OpenTelemetry.Exporter.OpenTelemetryProtocol.dll!OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation.OtlpLogRecordTransformer.BuildExportRequest(OpenTelemetry.Proto.Resource.V1.Resource processResource, OpenTelemetry.Batch<OpenTelemetry.Logs.LogRecord> logRecordBatch) Line 42
OpenTelemetry.Exporter.OpenTelemetryProtocol.dll!OpenTelemetry.Exporter.OtlpLogExporter.Export(OpenTelemetry.Batch<OpenTelemetry.Logs.LogRecord> logRecordBatch) Line 55
OpenTelemetry.dll!OpenTelemetry.BatchExportProcessor<OpenTelemetry.Logs.LogRecord>.ExporterProc()
from opentelemetry-dotnet.
On my computer, I often (not every time) get a NullReferenceException in Microsoft.Extensions.Telemetry.dll!Microsoft.Extensions.Logging.JustInTimeRedactor.ToString
This is something to be reported to the owners of Microsoft.Extensions.Telemetry
itself.
The issue is on a separated thread OpenTelemetry-BatchExportProcessor-OtlpLogExporter and the stack trace is the following:
Are you seeing this exception escaping or its caught by OTLPExporter and proceeds without crashing the app?
https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/Shared/TagTransformer.cs#L63-L74 is the place where the exception is thrown (and caught correctly as well). I am guessing the issue is with the JustInTimeRedactor
itself, that it is incorrectly assuming the state can remain after the Log
call is over..... (I don't have cycles to take a deeper look to confirm this...)
@CodeBlanch who fixed similar issue in the OTel SDK itself.
from opentelemetry-dotnet.
I removed the bug tag. When I saw "pool", I initially assumed the LogRecord pooling in this repo, but since then, it is clear that you were referring to the pooling done inside JustInTimeRedactor.
from opentelemetry-dotnet.
This is something to be reported to the owners of Microsoft.Extensions.Telemetry itself.
I'll try to report the issue on the other repo, but as you said at first glance it's ok to assume that after leaving Log in OpenTelemetryLogger the attributes are safe to collect as they should be "frozen" or projected to something safe. Like I do in my workaround.
Are you seeing this exception escaping or its caught by OTLPExporter and proceeds without crashing the app?
I catch it because for debugging purpose I configured VS to catch any CLR exception. With regular settings, it indeed doesn't break. However, in such case I don't have the attribute flowing in my log pipeline.
from opentelemetry-dotnet.
Hey @cijothomas, thanks for looking into this. As explained by @geeknoid in this comment we believe that the issue lies in OTel here as it shouldn't try to call ToString on object references that it keeps around as it cannot be guaranteed that doing so is safe (objects might be disposed, nulled out, or simply in a state that is no longer valid).
from opentelemetry-dotnet.
Hey @cijothomas, thanks for looking into this. As explained by @geeknoid in this comment we believe that the issue lies in OTel here as it shouldn't try to call ToString on object references that it keeps around as it cannot be guaranteed that doing so is safe (objects might be disposed, nulled out, or simply in a state that is no longer valid).
As suggested here, OTel SDK is expected to read everything off the state in the sync path itself. If it is not working, then it is a bug in OTel .NET sdk. Would you make a minimal repro app to confirm if this is indeed an issue in OTel .NET?
OTel code section doing the buffering: https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry/Logs/LogRecord.cs#L475-L485
from opentelemetry-dotnet.
I don't believe value is IDisposable || value is IResettable
will recognize all limited-lifetime types that can be logged.
from opentelemetry-dotnet.
Related Issues (20)
- Prometheus exporter produces zero-byte HTTP response HOT 5
- Unify resource builder usage between Logging and Metrics/Tracing HOT 1
- Mark ActivityExtensions.RecordException obsolete HOT 5
- How does OTel semver conention work? HOT 2
- Baggage propagation is not possible for instrumentations without depending on OpenTelemetry.Api package HOT 13
- Specifying an endpoint in appsettings.json breaks appending suffix to endpoint path HOT 1
- Add a top-level `UseDebugExporter()` convenience method. HOT 2
- Adding filter processor after also filter previous processor HOT 5
- [BaggagePropagator] handle baggage properties
- OpenTelemetryLoggerOptions.IncludeScopes does not add scopes to logs HOT 6
- Tutorial of `getting-started-aspnetcore` is not working as it refers un-released API HOT 2
- Baggage propagation - known issues
- [Question] Trace attribute http.route vs url.path HOT 4
- HttpProtobuf doesn't work on dotNet Android project
- Support .NET 9 ActivitySource Tags HOT 2
- LogLevel configuration (appSettings.json) for OpenTelemetry provider not working on Functions app using HostBuilder without defaults HOT 14
- Detect `service.version` from Assembly Version? HOT 2
- Create a destination file with name derived from OTel log attribute HOT 3
- ArraySegment ArgumentException in PrometheusCollectionManager on results write HOT 2
- Metrics page may appear blank after a few seconds. HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from opentelemetry-dotnet.