* Use value from UDC event payload.
* Adding support for UpDownCounter reporting a value instead of a rate
* Check for payload version, don't attempt to parse if version 0
* Don't get rate for updowncounter payload
}
}
+ internal class UpDownCounterPayload : CounterPayload
+ {
+ public UpDownCounterPayload(string providerName, string name, string displayName, string displayUnits, string metadata, double value, DateTime timestamp) :
+ base(providerName, name, metadata, value, timestamp, "Metric", EventType.UpDownCounter)
+ {
+ // In case these properties are not provided, set them to appropriate values.
+ string counterName = string.IsNullOrEmpty(displayName) ? name : displayName;
+ DisplayName = !string.IsNullOrEmpty(displayUnits) ? $"{counterName} ({displayUnits})" : counterName;
+ }
+ }
+
internal class CounterEndedPayload : CounterPayload
{
public CounterEndedPayload(string providerName, string name, DateTime timestamp)
Rate,
Gauge,
Histogram,
+ UpDownCounter,
Error,
CounterEnded
}
{
HandleCounterRate(traceEvent, filter, sessionId, out payload);
}
+ else if (traceEvent.EventName == "UpDownCounterRateValuePublished")
+ {
+ HandleUpDownCounterValue(traceEvent, filter, sessionId, out payload);
+ }
else if (traceEvent.EventName == "TimeSeriesLimitReached")
{
HandleTimeSeriesLimitReached(traceEvent, sessionId, out payload);
else
{
// for observable instruments we assume the lack of data is meaningful and remove it from the UI
- // this happens when the ObservableCounter callback function throws an exception.
+ // this happens when the ObservableCounter callback function throws an exception
+ // or when the ObservableCounter doesn't include a measurement for a particular set of tag values.
+ payload = new CounterEndedPayload(meterName, instrumentName, traceEvent.TimeStamp);
+ }
+ }
+
+ private static void HandleUpDownCounterValue(TraceEvent traceEvent, CounterFilter filter, string sessionId, out ICounterPayload payload)
+ {
+ payload = null;
+
+ string payloadSessionId = (string)traceEvent.PayloadValue(0);
+
+ if (payloadSessionId != sessionId || traceEvent.Version < 1) // Version 1 added the value field.
+ {
+ return;
+ }
+
+ string meterName = (string)traceEvent.PayloadValue(1);
+ //string meterVersion = (string)obj.PayloadValue(2);
+ string instrumentName = (string)traceEvent.PayloadValue(3);
+ string unit = (string)traceEvent.PayloadValue(4);
+ string tags = (string)traceEvent.PayloadValue(5);
+ //string rateText = (string)traceEvent.PayloadValue(6); // Not currently using rate for UpDownCounters.
+ string valueText = (string)traceEvent.PayloadValue(7);
+
+ if (!filter.IsIncluded(meterName, instrumentName))
+ {
+ return;
+ }
+
+ if (double.TryParse(valueText, NumberStyles.Number | NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
+ {
+ // UpDownCounter reports the value, not the rate - this is different than how Counter behaves.
+ payload = new UpDownCounterPayload(meterName, instrumentName, null, unit, tags, value, traceEvent.TimeStamp);
+
+ }
+ else
+ {
+ // for observable instruments we assume the lack of data is meaningful and remove it from the UI
+ // this happens when the ObservableUpDownCounter callback function throws an exception
+ // or when the ObservableUpDownCounter doesn't include a measurement for a particular set of tag values.
payload = new CounterEndedPayload(meterName, instrumentName, traceEvent.TimeStamp);
}
}
{
HandleCounterRate(obj);
}
+ else if (obj.EventName == "UpDownCounterRateValuePublished")
+ {
+ HandleUpDownCounterValue(obj);
+ }
else if (obj.EventName == "TimeSeriesLimitReached")
{
HandleTimeSeriesLimitReached(obj);
}
}
+ private void HandleUpDownCounterValue(TraceEvent obj)
+ {
+ if (obj.Version < 1) // Version 1 added the value field.
+ {
+ return;
+ }
+
+ string sessionId = (string)obj.PayloadValue(0);
+ string meterName = (string)obj.PayloadValue(1);
+ //string meterVersion = (string)obj.PayloadValue(2);
+ string instrumentName = (string)obj.PayloadValue(3);
+ string unit = (string)obj.PayloadValue(4);
+ string tags = (string)obj.PayloadValue(5);
+ //string rateText = (string)obj.PayloadValue(6); // Not currently using rate for UpDownCounters.
+ string valueText = (string)obj.PayloadValue(7);
+ if (sessionId != _metricsEventSourceSessionId)
+ {
+ return;
+ }
+ MeterInstrumentEventObserved(meterName, obj.TimeStamp);
+
+ // the value might be an empty string indicating no measurement was provided this collection interval
+ if (double.TryParse(valueText, NumberStyles.Number | NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
+ {
+ // UpDownCounter reports the value, not the rate - this is different than how Counter behaves, and is thus treated as a gauge.
+ CounterPayload payload = new GaugePayload(meterName, instrumentName, null, unit, tags, value, obj.TimeStamp);
+ _renderer.CounterPayloadReceived(payload, _pauseCmdSet);
+ }
+ else
+ {
+ // for observable instruments we assume the lack of data is meaningful and remove it from the UI
+ CounterPayload payload = new RatePayload(meterName, instrumentName, null, unit, tags, 0, _interval, obj.TimeStamp);
+ _renderer.CounterStopped(payload);
+ }
+ }
+
private void HandleHistogram(TraceEvent obj)
{
string sessionId = (string)obj.PayloadValue(0);