More Corelib cleanup (dotnet/coreclr#26872)
[mono-project.git] / netcore / System.Private.CoreLib / shared / System / Diagnostics / Tracing / IncrementingPollingCounter.cs
blob0cdbac7e6a07a94cb5a7c727ad0e06ecd251e26a
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 #if ES_BUILD_STANDALONE
6 using System;
7 #endif
9 #if ES_BUILD_STANDALONE
10 namespace Microsoft.Diagnostics.Tracing
11 #else
12 namespace System.Diagnostics.Tracing
13 #endif
15 /// <summary>
16 /// IncrementingPollingCounter is a variant of EventCounter for variables that are ever-increasing.
17 /// Ex) # of exceptions in the runtime.
18 /// It does not calculate statistics like mean, standard deviation, etc. because it only accumulates
19 /// the counter value.
20 /// Unlike IncrementingEventCounter, this takes in a polling callback that it can call to update
21 /// its own metric periodically.
22 /// </summary>
23 public partial class IncrementingPollingCounter : DiagnosticCounter
25 /// <summary>
26 /// Initializes a new instance of the <see cref="IncrementingPollingCounter"/> class.
27 /// IncrementingPollingCounter live as long as the EventSource that they are attached to unless they are
28 /// explicitly Disposed.
29 /// </summary>
30 /// <param name="name">The name.</param>
31 /// <param name="eventSource">The event source.</param>
32 public IncrementingPollingCounter(string name, EventSource eventSource, Func<double> totalValueProvider) : base(name, eventSource)
34 if (totalValueProvider == null)
35 throw new ArgumentNullException(nameof(totalValueProvider));
37 _totalValueProvider = totalValueProvider;
38 Publish();
41 public override string ToString() => $"IncrementingPollingCounter '{Name}' Increment {_increment}";
43 public TimeSpan DisplayRateTimeScale { get; set; }
44 private double _increment;
45 private double _prevIncrement;
46 private readonly Func<double> _totalValueProvider;
48 /// <summary>
49 /// Calls "_totalValueProvider" to enqueue the counter value to the queue.
50 /// </summary>
51 internal void UpdateMetric()
53 try
55 lock (this)
57 _prevIncrement = _increment;
58 _increment = _totalValueProvider();
61 catch (Exception ex)
63 ReportOutOfBandMessage($"ERROR: Exception during EventCounter {Name} getMetricFunction callback: " + ex.Message);
67 internal override void WritePayload(float intervalSec, int pollingIntervalMillisec)
69 UpdateMetric();
70 lock (this) // Lock the counter
72 IncrementingCounterPayload payload = new IncrementingCounterPayload();
73 payload.Name = Name;
74 payload.DisplayName = DisplayName ?? "";
75 payload.DisplayRateTimeScale = (DisplayRateTimeScale == TimeSpan.Zero) ? "" : DisplayRateTimeScale.ToString("c");
76 payload.IntervalSec = intervalSec;
77 payload.Series = $"Interval={pollingIntervalMillisec}"; // TODO: This may need to change when we support multi-session
78 payload.CounterType = "Sum";
79 payload.Metadata = GetMetadataString();
80 payload.Increment = _increment - _prevIncrement;
81 payload.DisplayUnits = DisplayUnits ?? "";
82 EventSource.Write("EventCounters", new EventSourceOptions() { Level = EventLevel.LogAlways }, new IncrementingPollingCounterPayloadType(payload));
87 /// <summary>
88 /// This is the payload that is sent in the with EventSource.Write
89 /// </summary>
90 [EventData]
91 internal class IncrementingPollingCounterPayloadType
93 public IncrementingPollingCounterPayloadType(IncrementingCounterPayload payload) { Payload = payload; }
94 public IncrementingCounterPayload Payload { get; set; }