-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
On .NET Framework, if the protected void RecordMeasurement(T measurement, in TagList tagList) method of System.Diagnostics.Metrics.Instrument<T> is given an empty TagList tagList, then the method does not record T measurement.
Reproduction Steps
NoTags.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="8.0.0" />
</ItemGroup>
</Project>Program.cs:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
namespace NoTags
{
internal static class Program
{
private static void Main()
{
using (MeterListener meterListener = new MeterListener())
using (Meter meter = new Meter("demo"))
{
Counter<int> first = meter.CreateCounter<int>("first");
Counter<int> second = meter.CreateCounter<int>("second");
Counter<int> third = meter.CreateCounter<int>("third");
Counter<int> fourth = meter.CreateCounter<int>("fourth");
meterListener.SetMeasurementEventCallback<int>(ShowMeasurement);
meterListener.EnableMeasurementEvents(first);
meterListener.EnableMeasurementEvents(second);
meterListener.EnableMeasurementEvents(third);
meterListener.EnableMeasurementEvents(fourth);
first.Add(1); // OK
second.Add(1, new TagList()); // lost
third.Add(1, Array.Empty<KeyValuePair<string, object>>()); // OK
fourth.Add(1, new TagList(Array.Empty<KeyValuePair<string, object>>())); // lost
}
}
private static void ShowMeasurement<T>(
Instrument instrument,
T measurement,
ReadOnlySpan<KeyValuePair<string, object>> tags,
object state)
{
Console.WriteLine($"{instrument.Name} = {measurement}");
}
}
}Run this program on each target framework.
Expected behavior
Each Add call should trigger the measurement callback of the MeterListener. The behaviour should be the same on .NET Framework and .NET.
$ dotnet run --framework=net8.0
first = 1
second = 1
third = 1
fourth = 1
$ dotnet run --framework=net48
first = 1
second = 1
third = 1
fourth = 1
Actual behavior
On .NET Framework only, the Add calls that pass in an empty TagList do not trigger the measurement callback of the MeterListener. However, the Add calls that do not involve a TagList parameter still trigger the callback, even though those calls don't have any tags either.
$ dotnet run --framework=net8.0
first = 1
second = 1
third = 1
fourth = 1
$ dotnet run --framework=net48
first = 1
third = 1
Regression?
Not a regression: version 6.0.0 of the System.Diagnostics.DiagnosticSource package already has this bug on .NET Framework, and earlier versions do not define the TagList type.
Known Workarounds
If you don't have tags, then don't use the overload that has a TagList parameter.
Configuration
System.Diagnostics.DiagnosticSource 8.0.0 on .NET Framework 4.8 on Windows 10 version 22H2 x64.
Built using .NET SDK 8.0.101.
The bug affects only software built targeting .NET Framework.
Other information
This return statement and its comment are not right:
Line 96 in 5535e31
| case 0: return; // no need to report anything |