-
Notifications
You must be signed in to change notification settings - Fork 772
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
Fix NullReferenceException caught by SDK when metric has a tag with a null value #3325
Fix NullReferenceException caught by SDK when metric has a tag with a null value #3325
Conversation
Codecov Report
@@ Coverage Diff @@
## main #3325 +/- ##
=======================================
Coverage 85.42% 85.43%
=======================================
Files 270 270
Lines 9560 9561 +1
=======================================
+ Hits 8167 8168 +1
Misses 1393 1393
|
good find.. need to see how other languages deal with this. (or is it only an issue in .net)... |
|
I think it is in part a .NET-only issue given that our attributes can be of any
👍 I'm good with making this an exporter concern. Regarding null values, the spec says.
So, it'd be up to us to decide how to handle them in the OTLP and Prometheus exporters. OTLPThe proto has this comment
So our options would be:
PrometheusI'm less familiar with things here. The Prometheus format states:
So should the value of a null-valued label just be |
You've probably seen it from PR review 😃 opentelemetry-dotnet/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusSerializer.cs Line 230 in fa21e1e
|
Ha, yes! It was this comment I saw. I saw it as I was expanding the tests on #3312. |
So I think this PR is good to go. I'll follow up and make sure the exporters handle null values ok. I suspect they might be ok because this was handled with my work with the tag transformer stuff. |
@@ -42,6 +42,39 @@ public MetricApiTest(ITestOutputHelper output) | |||
this.output = output; | |||
} | |||
|
|||
[Fact] | |||
public void MeasurementWithNullValuedTag() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯
Do you want this to be part of 1.3.0 which I expect to release tomorrow.? If not, lets hold off merging for a day. |
It's probably not a common issue, so good to go after 1.3.0. |
@alanwest could you fix conflict and we are good to merge. |
unchecked | ||
{ | ||
var hash = 17; | ||
for (int i = 0; i < this.Keys.Length; i++) | ||
{ | ||
hash = (hash * 31) + this.Keys[i].GetHashCode() + this.Values[i]?.GetHashCode() ?? 0; | ||
} | ||
|
||
this.hashCode = hash; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any concern that the underlying values of Keys or Values will get changed since the array indexes can still be written to but the hash won't be updated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tgrieger-sf No because the the keys and values never do change. This struct is internal and instances of it are only used within our AggregatorStore for looking up metric points
private readonly ConcurrentDictionary<Tags, int> tagsToMetricPointIndexDictionary = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If that's the case, is there any benefit in using ReadOnlySpan<string/object>
for Keys and Values to make it explicit?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ReadOnlySpan
is a ref struct
and cannot be used a valid type for a dictionary as it has to live on stack.
When recording a metric with a null-valued tag the following code throws a NullReferenceException causing the measurement to be ignored. This code is invoked when locating the MetricPoint in the AggregationStore.
opentelemetry-dotnet/src/OpenTelemetry/Metrics/Tags.cs
Lines 87 to 90 in 56d6677
The exception is caught here
opentelemetry-dotnet/src/OpenTelemetry/Metrics/AggregatorStore.cs
Lines 343 to 346 in 56d6677
Fixed it so that measurements with null-valued tags are not ignored. The null-valued tag is passed through. There's some follow on work needed to ensure exporters can handle null values. See: #3325 (comment)