コード例 #1
0
ファイル: CounterMonitor.cs プロジェクト: jorive/diagnostics
        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);
            }
        }