Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
 public DiagnosticsMonitor(MonitoringSourceConfiguration sourceConfig)
 {
     _sourceConfig         = sourceConfig;
     _stopProcessingSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
 }
Пример #4
0
        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);
        }
Пример #5
0
 public EventPipeStreamProvider(MonitoringSourceConfiguration sourceConfig)
 {
     _sourceConfig         = sourceConfig;
     _stopProcessingSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
 }