Exemple #1
0
        // when receiving DiagnosticCounter events we may have buffered them to wait for
        // duplicate instrument events. If we've waited long enough then we should remove
        // them from the buffer and render them.
        private void HandleBufferedEvents()
        {
            DateTime now = DateTime.Now;

            lock (this)
            {
                while (_bufferedEvents.Count != 0)
                {
                    CounterPayload     payload            = _bufferedEvents.Peek();
                    ProviderEventState providerEventState = _providerEventStates[payload.ProviderName];
                    if (providerEventState.InstrumentEventObserved)
                    {
                        _bufferedEvents.Dequeue();
                    }
                    else if (providerEventState.FirstReceiveTimestamp + TimeSpan.FromSeconds(BufferDelaySecs) < now)
                    {
                        _bufferedEvents.Dequeue();
                        _renderer.CounterPayloadReceived(payload, _pauseCmdSet);
                    }
                    else
                    {
                        // technically an event that is eligible to be unbuffered earlier could be waiting behind a
                        // buffered event that will wait longer, but we don't expect this variation to matter for
                        // our scenarios. At worst an event might wait up to 2*BufferDelaySecs. If there is a scenario
                        // where it matters we could scan the entire queue rather than just the front of it.
                        break;
                    }
                }
            }
        }
Exemple #2
0
 private void MeterInstrumentEventObserved(string meterName, string instrumentName, DateTime timestamp)
 {
     if (!_providerEventStates.TryGetValue(meterName, out ProviderEventState providerEventState))
     {
         providerEventState = new ProviderEventState()
         {
             FirstReceiveTimestamp   = timestamp,
             InstrumentEventObserved = true
         };
         _providerEventStates.Add(meterName, providerEventState);
     }
     else
     {
         providerEventState.InstrumentEventObserved = true;
     }
 }
Exemple #3
0
        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);
            }
        }