Skip to content

Commit dfe1076

Browse files
authored
Publish UpDownCounter and ObservableUpDownCounter Events for System.Diagnostics.Metrics (#81041)
Add support for publishing UpDownCounter (and Observable...) - also added in the missing testing for this.
1 parent 84a7b8e commit dfe1076

File tree

5 files changed

+186
-21
lines changed

5 files changed

+186
-21
lines changed

src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/AggregationManager.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ private void RemoveInstrumentState(Instrument instrument)
275275
{
276276
lock (this)
277277
{
278-
return CheckTimeSeriesAllowed() ? new RateSumAggregator() : null;
278+
return CheckTimeSeriesAllowed() ? new RateSumAggregator(isMonotonic: true) : null;
279279
}
280280
};
281281
}
@@ -285,7 +285,7 @@ private void RemoveInstrumentState(Instrument instrument)
285285
{
286286
lock (this)
287287
{
288-
return CheckTimeSeriesAllowed() ? new RateAggregator() : null;
288+
return CheckTimeSeriesAllowed() ? new RateAggregator(isMonotonic: true) : null;
289289
}
290290
};
291291
}
@@ -312,6 +312,26 @@ private void RemoveInstrumentState(Instrument instrument)
312312
}
313313
};
314314
}
315+
else if (genericDefType == typeof(UpDownCounter<>))
316+
{
317+
return () =>
318+
{
319+
lock (this)
320+
{
321+
return CheckTimeSeriesAllowed() ? new RateSumAggregator(isMonotonic: false) : null;
322+
}
323+
};
324+
}
325+
else if (genericDefType == typeof(ObservableUpDownCounter<>))
326+
{
327+
return () =>
328+
{
329+
lock (this)
330+
{
331+
return CheckTimeSeriesAllowed() ? new RateAggregator(isMonotonic: false) : null;
332+
}
333+
};
334+
}
315335
else
316336
{
317337
return null;

src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/MetricsEventSource.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ public void MultipleSessionsNotSupportedError(string runningSessionId)
191191
WriteEvent(15, runningSessionId);
192192
}
193193

194+
[Event(16, Keywords = Keywords.TimeSeriesValues)]
195+
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
196+
Justification = "This calls WriteEvent with all primitive arguments which is safe. Primitives are always serialized properly.")]
197+
public void UpDownCounterRateValuePublished(string sessionId, string meterName, string? meterVersion, string instrumentName, string? unit, string tags, string rate)
198+
{
199+
WriteEvent(16, sessionId, meterName, meterVersion ?? "", instrumentName, unit ?? "", tags, rate);
200+
}
201+
194202
/// <summary>
195203
/// Called when the EventSource gets a command from a EventListener or ETW.
196204
/// </summary>
@@ -407,8 +415,16 @@ private static void TransmitMetricValue(Instrument instrument, LabeledAggregatio
407415
{
408416
if (stats.AggregationStatistics is RateStatistics rateStats)
409417
{
410-
Log.CounterRateValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, FormatTags(stats.Labels),
411-
rateStats.Delta.HasValue ? rateStats.Delta.Value.ToString(CultureInfo.InvariantCulture) : "");
418+
if (rateStats.IsMonotonic)
419+
{
420+
Log.CounterRateValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, FormatTags(stats.Labels),
421+
rateStats.Delta.HasValue ? rateStats.Delta.Value.ToString(CultureInfo.InvariantCulture) : "");
422+
}
423+
else
424+
{
425+
Log.UpDownCounterRateValuePublished(sessionId, instrument.Meter.Name, instrument.Meter.Version, instrument.Name, instrument.Unit, FormatTags(stats.Labels),
426+
rateStats.Delta.HasValue ? rateStats.Delta.Value.ToString(CultureInfo.InvariantCulture) : "");
427+
}
412428
}
413429
else if (stats.AggregationStatistics is LastValueStatistics lastValueStats)
414430
{

src/libraries/System.Diagnostics.DiagnosticSource/src/System/Diagnostics/Metrics/RateAggregator.cs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ namespace System.Diagnostics.Metrics
66
internal sealed class RateSumAggregator : Aggregator
77
{
88
private double _sum;
9+
private bool _isMonotonic;
10+
11+
public RateSumAggregator(bool isMonotonic)
12+
{
13+
_isMonotonic = isMonotonic;
14+
}
915

1016
public override void Update(double value)
1117
{
@@ -19,7 +25,7 @@ public override IAggregationStatistics Collect()
1925
{
2026
lock (this)
2127
{
22-
RateStatistics? stats = new RateStatistics(_sum);
28+
RateStatistics? stats = new RateStatistics(_sum, _isMonotonic);
2329
_sum = 0;
2430
return stats;
2531
}
@@ -30,6 +36,12 @@ internal sealed class RateAggregator : Aggregator
3036
{
3137
private double? _prevValue;
3238
private double _value;
39+
private bool _isMonotonic;
40+
41+
public RateAggregator(bool isMonotonic)
42+
{
43+
_isMonotonic = isMonotonic;
44+
}
3345

3446
public override void Update(double value)
3547
{
@@ -48,7 +60,7 @@ public override IAggregationStatistics Collect()
4860
{
4961
delta = _value - _prevValue.Value;
5062
}
51-
RateStatistics stats = new RateStatistics(delta);
63+
RateStatistics stats = new RateStatistics(delta, _isMonotonic);
5264
_prevValue = _value;
5365
return stats;
5466
}
@@ -57,11 +69,14 @@ public override IAggregationStatistics Collect()
5769

5870
internal sealed class RateStatistics : IAggregationStatistics
5971
{
60-
public RateStatistics(double? delta)
72+
public RateStatistics(double? delta, bool isMonotonic)
6173
{
6274
Delta = delta;
75+
IsMonotonic = isMonotonic;
6376
}
6477

6578
public double? Delta { get; }
79+
80+
public bool IsMonotonic { get; }
6681
}
6782
}

0 commit comments

Comments
 (0)