private void HandleCounterRate(TraceEvent obj) { 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); if (sessionId != _metricsEventSourceSessionId) { return; } MeterInstrumentEventObserved(meterName, instrumentName, obj.TimeStamp); // the value might be an empty string indicating no measurement was provided this collection interval if (double.TryParse(rateText, out double rate)) { CounterPayload payload = new RatePayload(meterName, instrumentName, null, unit, tags, rate, _interval, obj.TimeStamp); _renderer.CounterPayloadReceived(payload, _pauseCmdSet); } }
private void HandleDiagnosticCounter(TraceEvent obj) { IDictionary <string, object> payloadVal = (IDictionary <string, object>)(obj.PayloadValue(0)); IDictionary <string, object> payloadFields = (IDictionary <string, object>)(payloadVal["Payload"]); // If it's not a counter we asked for, ignore it. string name = payloadFields["Name"].ToString(); if (!_counterList.Contains(obj.ProviderName, name)) { return; } // init providerEventState if this is the first time we've seen an event from this provider if (!_providerEventStates.TryGetValue(obj.ProviderName, out ProviderEventState providerState)) { providerState = new ProviderEventState() { FirstReceiveTimestamp = obj.TimeStamp }; _providerEventStates.Add(obj.ProviderName, providerState); } // we give precedence to instrument events over diagnostic counter events. If we are seeing // both then drop this one. if (providerState.InstrumentEventObserved) { return; } CounterPayload payload = null; if (payloadFields["CounterType"].Equals("Sum")) { payload = new RatePayload( obj.ProviderName, name, payloadFields["DisplayName"].ToString(), payloadFields["DisplayUnits"].ToString(), null, (double)payloadFields["Increment"], _interval, obj.TimeStamp); } else { payload = new GaugePayload( obj.ProviderName, name, payloadFields["DisplayName"].ToString(), payloadFields["DisplayUnits"].ToString(), null, (double)payloadFields["Mean"], obj.TimeStamp); } // If we saw the first event for this provider recently then a duplicate instrument event may still be // coming. We'll buffer this event for a while and then render it if it remains unduplicated for // a while. // This is all best effort, if we do show the DiagnosticCounter event and then an instrument event shows up // later the renderer may obsserve some odd behavior like changes in the counter metadata, oddly timed reporting // intervals, or counters that stop reporting. // I'm gambling this is good enough that the behavior will never be seen in practice, but if it is we could // either adjust the time delay or try to improve how the renderers handle it. if (providerState.FirstReceiveTimestamp + TimeSpan.FromSeconds(BufferDelaySecs) >= obj.TimeStamp) { _bufferedEvents.Enqueue(payload); } else { _renderer.CounterPayloadReceived(payload, _pauseCmdSet); } }