public DiagnosticsEventPipeProcessor( PipeMode mode, ILoggerFactory loggerFactory = null, // PipeMode = Logs LogLevel logsLevel = LogLevel.Debug, // PipeMode = Logs IEnumerable <ICountersLogger> metricLoggers = null, // PipeMode = Metrics int metricIntervalSeconds = 10, // PipeMode = Metrics CounterFilter metricFilter = null, // PipeMode = Metrics MemoryGraph gcGraph = null, // PipeMode = GCDump MonitoringSourceConfiguration configuration = null, // PipeMode = Nettrace Func <Stream, CancellationToken, Task> onStreamAvailable = null, // PipeMode = Nettrace Func <string, CancellationToken, Task> processInfoCallback = null // PipeMode = ProcessInfo ) { _metricLoggers = metricLoggers ?? Enumerable.Empty <ICountersLogger>(); _mode = mode; _loggerFactory = loggerFactory; _gcGraph = gcGraph; _metricIntervalSeconds = metricIntervalSeconds; _logsLevel = logsLevel; _processInfoCallback = processInfoCallback; _userConfig = configuration; _onStreamAvailable = onStreamAvailable; _processInfoCallback = processInfoCallback; _counterFilter = metricFilter; _sessionStarted = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); }
public static bool TryGetCounterPayload(this TraceEvent traceEvent, CounterFilter filter, out ICounterPayload payload) { payload = null; if ("EventCounters".Equals(traceEvent.EventName)) { IDictionary <string, object> payloadVal = (IDictionary <string, object>)(traceEvent.PayloadValue(0)); IDictionary <string, object> payloadFields = (IDictionary <string, object>)(payloadVal["Payload"]); //Make sure we are part of the requested series. If multiple clients request metrics, all of them get the metrics. string series = payloadFields["Series"].ToString(); string counterName = payloadFields["Name"].ToString(); //CONSIDER //Concurrent counter sessions do not each get a separate interval. Instead the payload //for _all_ the counters changes the Series to be the lowest specified interval, on a per provider basis. //Currently the CounterFilter will remove any data whose Series doesn't match the requested interval. if (!filter.IsIncluded(traceEvent.ProviderName, counterName, GetInterval(series))) { return(false); } float intervalSec = (float)payloadFields["IntervalSec"]; string displayName = payloadFields["DisplayName"].ToString(); string displayUnits = payloadFields["DisplayUnits"].ToString(); double value = 0; CounterType counterType = CounterType.Metric; if (payloadFields["CounterType"].Equals("Mean")) { value = (double)payloadFields["Mean"]; } else if (payloadFields["CounterType"].Equals("Sum")) { counterType = CounterType.Rate; value = (double)payloadFields["Increment"]; if (string.IsNullOrEmpty(displayUnits)) { displayUnits = "count"; } //TODO Should we make these /sec like the dotnet-counters tool? } // Note that dimensional data such as pod and namespace are automatically added in prometheus and azure monitor scenarios. // We no longer added it here. payload = new CounterPayload( traceEvent.TimeStamp, traceEvent.ProviderName, counterName, displayName, displayUnits, value, counterType, intervalSec); return(true); } return(false); }
public EventCounterPipeline(DiagnosticsClient client, EventPipeCounterPipelineSettings settings, IEnumerable <ICountersLogger> loggers) : base(client, settings) { _loggers = loggers ?? throw new ArgumentNullException(nameof(loggers)); if (settings.CounterGroups.Length > 0) { _filter = new CounterFilter(CounterIntervalSeconds); foreach (var counterGroup in settings.CounterGroups) { _filter.AddFilter(counterGroup.ProviderName, counterGroup.CounterNames); } } else { _filter = CounterFilter.AllCounters(CounterIntervalSeconds); } }