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 DiagnosticsEventPipeProcessor( MonitoringSourceConfiguration configuration, Func <EventPipeEventSource, Func <Task>, CancellationToken, Task> onEventSourceAvailable ) { _configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); _onEventSourceAvailable = onEventSourceAvailable ?? throw new ArgumentNullException(nameof(onEventSourceAvailable)); _sessionStarted = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); }
public DiagnosticsMonitor(MonitoringSourceConfiguration sourceConfig) { _sourceConfig = sourceConfig; _stopProcessingSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); }
public async Task Process(DiagnosticsClient client, TimeSpan duration, CancellationToken token) { //No need to guard against reentrancy here, since the calling pipeline does this already. IDisposable registration = token.Register(() => _sessionStarted.TrySetCanceled()); await await Task.Factory.StartNew(async() => { EventPipeEventSource source = null; DiagnosticsMonitor monitor = null; Task handleEventsTask = Task.CompletedTask; try { MonitoringSourceConfiguration config = null; if (_mode == PipeMode.Logs) { config = new LoggingSourceConfiguration(_logsLevel); } else if (_mode == PipeMode.Metrics) { config = new MetricSourceConfiguration(_metricIntervalSeconds, _counterFilter.GetProviders()); } else if (_mode == PipeMode.GCDump) { config = new GCDumpSourceConfiguration(); } else if (_mode == PipeMode.ProcessInfo) { config = new SampleProfilerConfiguration(); } else if (_mode == PipeMode.Nettrace) { config = _userConfig; } monitor = new DiagnosticsMonitor(config); // Allows the event handling routines to stop processing before the duration expires. Func <Task> stopFunc = () => Task.Run(() => { monitor.StopProcessing(); }); Stream sessionStream = await monitor.ProcessEvents(client, duration, token); if (_mode == PipeMode.Nettrace) { if (!_sessionStarted.TrySetResult(true)) { token.ThrowIfCancellationRequested(); } lock (_lock) { //Save the stop function for later, so that we can stop a trace later. _stopFunc = stopFunc; } await _onStreamAvailable(sessionStream, token); return; } source = new EventPipeEventSource(sessionStream); if (_mode == PipeMode.Metrics) { // Metrics HandleEventCounters(source); } else if (_mode == PipeMode.Logs) { // Logging HandleLoggingEvents(source); } else if (_mode == PipeMode.GCDump) { // GC handleEventsTask = HandleGCEvents(source, stopFunc, token); } else if (_mode == PipeMode.ProcessInfo) { // ProcessInfo handleEventsTask = HandleProcessInfo(source, stopFunc, token); } lock (_lock) { _eventPipeSession = source; _stopFunc = stopFunc; } registration.Dispose(); if (!_sessionStarted.TrySetResult(true)) { token.ThrowIfCancellationRequested(); } source.Process(); token.ThrowIfCancellationRequested(); } catch (DiagnosticsClientException ex) { throw new InvalidOperationException("Failed to start the event pipe session", ex); } finally { ExecuteCounterLoggerAction((metricLogger) => metricLogger.PipelineStopped()); registration.Dispose(); EventPipeEventSource session = null; lock (_lock) { session = _eventPipeSession; _eventPipeSession = null; } session?.Dispose(); if (monitor != null) { await monitor.DisposeAsync(); } } // Await the task returned by the event handling method AFTER the EventPipeEventSource is disposed. // The EventPipeEventSource will only raise the Completed event when it is disposed. So if this task // is waiting for the Completed event to be raised, it will never complete until after EventPipeEventSource // is diposed. await handleEventsTask; }, token, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
public EventPipeStreamProvider(MonitoringSourceConfiguration sourceConfig) { _sourceConfig = sourceConfig; _stopProcessingSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously); }