public Task <ActionResult <IEnumerable <Models.ProcessIdentifier> > > GetProcesses()
        {
            return(this.InvokeService(async() =>
            {
                IProcessInfo defaultProcessInfo = null;
                try
                {
                    defaultProcessInfo = await _diagnosticServices.GetProcessAsync(null, HttpContext.RequestAborted);
                }
                catch (Exception)
                {
                    // Unable to locate a default process; no action required
                }

                IList <Models.ProcessIdentifier> processesIdentifiers = new List <Models.ProcessIdentifier>();
                foreach (IProcessInfo p in await _diagnosticServices.GetProcessesAsync(processFilter: null, HttpContext.RequestAborted))
                {
                    processesIdentifiers.Add(new Models.ProcessIdentifier()
                    {
                        Pid = p.EndpointInfo.ProcessId,
                        Uid = p.EndpointInfo.RuntimeInstanceCookie,
                        Name = p.ProcessName,
                        IsDefault = (defaultProcessInfo != null &&
                                     p.EndpointInfo.ProcessId == defaultProcessInfo.EndpointInfo.ProcessId &&
                                     p.EndpointInfo.RuntimeInstanceCookie == defaultProcessInfo.EndpointInfo.RuntimeInstanceCookie)
                    });
                }
                _logger.WrittenToHttpStream();
                return new ActionResult <IEnumerable <Models.ProcessIdentifier> >(processesIdentifiers);
            }, _logger));
        }
Example #2
0
        private async Task <ActionResult <T> > InvokeForProcess <T>(Func <IProcessInfo, Task <ActionResult <T> > > func, ProcessFilter?filter, string artifactType = null)
        {
            IDisposable artifactTypeRegistration = null;

            if (!string.IsNullOrEmpty(artifactType))
            {
                KeyValueLogScope artifactTypeScope = new KeyValueLogScope();
                artifactTypeScope.AddArtifactType(artifactType);
                artifactTypeRegistration = _logger.BeginScope(artifactTypeScope);
            }

            try
            {
                return(await this.InvokeService(async() =>
                {
                    IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(filter, HttpContext.RequestAborted);

                    KeyValueLogScope processInfoScope = new KeyValueLogScope();
                    processInfoScope.AddEndpointInfo(processInfo.EndpointInfo);
                    using var _ = _logger.BeginScope(processInfoScope);

                    _logger.LogDebug("Resolved target process.");

                    return await func(processInfo);
                }, _logger));
            }
            finally
            {
                artifactTypeRegistration?.Dispose();
            }
        }
Example #3
0
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return(Task.Run(async() =>
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    stoppingToken.ThrowIfCancellationRequested();

                    try
                    {
                        //TODO In multi-process scenarios, how do we decide which process to choose?
                        //One possibility is to enable metrics after a request to begin polling for metrics
                        IProcessInfo pi = await _services.GetProcessAsync(filter: null, stoppingToken);
                        _counterPipeline = new EventCounterPipeline(pi.Client, new EventPipeCounterPipelineSettings
                        {
                            CounterGroups = Array.Empty <EventPipeCounterGroup>(),
                            Duration = Timeout.InfiniteTimeSpan,
                            RefreshInterval = TimeSpan.FromSeconds(_options.UpdateIntervalSeconds)
                        }, metricsLogger: new[] { new MetricsLogger(_store.MetricsStore) });

                        await _counterPipeline.RunAsync(stoppingToken);
                    }
                    catch (Exception e) when(!(e is OperationCanceledException))
                    {
                        //Most likely we failed to resolve the pid. Attempt to do this again.
                        if (_counterPipeline != null)
                        {
                            await _counterPipeline.DisposeAsync();
                        }
                        await Task.Delay(5000);
                    }
                }
            }, stoppingToken));
        }
Example #4
0
        public Task <ActionResult> GetDump(
            ProcessFilter?processFilter,
            [FromQuery] DumpType type = DumpType.WithHeap)
        {
            return(this.InvokeService(async() =>
            {
                IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(processFilter, HttpContext.RequestAborted);
                Stream result = await _diagnosticServices.GetDump(processInfo, type, HttpContext.RequestAborted);

                string dumpFileName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
                                      FormattableString.Invariant($"dump_{GetFileNameTimeStampUtcNow()}.dmp") :
                                      FormattableString.Invariant($"core_{GetFileNameTimeStampUtcNow()}");

                //Compression is done automatically by the response
                //Chunking is done because the result has no content-length
                return File(result, "application/octet-stream", dumpFileName);
            }));
        }
Example #5
0
        public Task <ActionResult <ProcessModel> > GetProcess(
            ProcessFilter processFilter)
        {
            return(this.InvokeService <ProcessModel>(async() =>
            {
                IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync(
                    processFilter,
                    HttpContext.RequestAborted);

                return ProcessModel.FromProcessInfo(processInfo);
            }));
        }
Example #6
0
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            return(Task.Run(async() =>
            {
                while (!stoppingToken.IsCancellationRequested)
                {
                    stoppingToken.ThrowIfCancellationRequested();

                    try
                    {
                        //TODO In multi-process scenarios, how do we decide which process to choose?
                        //One possibility is to enable metrics after a request to begin polling for metrics
                        IProcessInfo pi = await _services.GetProcessAsync(filter: null, stoppingToken);
                        await _pipeProcessor.Process(pi.Client, pi.Pid, Timeout.InfiniteTimeSpan, stoppingToken);
                    }
                    catch (Exception e) when(!(e is OperationCanceledException))
                    {
                        //Most likely we failed to resolve the pid. Attempt to do this again.
                        await Task.Delay(5000);
                    }
                }
            }, stoppingToken));
        }
Example #7
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                stoppingToken.ThrowIfCancellationRequested();

                try
                {
                    IProcessInfo pi = await _services.GetProcessAsync(processKey : null, stoppingToken);

                    var client = new DiagnosticsClient(pi.EndpointInfo.Endpoint);

                    MetricsOptions       options        = _optionsMonitor.CurrentValue;
                    GlobalCounterOptions counterOptions = _counterOptions.CurrentValue;
                    using var optionsTokenSource = new CancellationTokenSource();

                    //If metric options change, we need to cancel the existing metrics pipeline and restart with the new settings.
                    using IDisposable monitorListener = _optionsMonitor.OnChange((_, _) => optionsTokenSource.SafeCancel());

                    EventPipeCounterPipelineSettings counterSettings = EventCounterSettingsFactory.CreateSettings(counterOptions, options);

                    _counterPipeline = new EventCounterPipeline(client, counterSettings, loggers: new[] { new MetricsLogger(_store.MetricsStore) });

                    using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken, optionsTokenSource.Token);
                    await _counterPipeline.RunAsync(linkedTokenSource.Token);
                }
                catch (Exception e) when(e is not OperationCanceledException || !stoppingToken.IsCancellationRequested)
                {
                    //Most likely we failed to resolve the pid or metric configuration change. Attempt to do this again.
                    if (_counterPipeline != null)
                    {
                        await _counterPipeline.DisposeAsync();
                    }
                    await Task.Delay(5000, stoppingToken);
                }
            }
        }
Example #8
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                stoppingToken.ThrowIfCancellationRequested();

                try
                {
                    //TODO In multi-process scenarios, how do we decide which process to choose?
                    //One possibility is to enable metrics after a request to begin polling for metrics
                    IProcessInfo pi = await _services.GetProcessAsync(filter : null, stoppingToken);

                    var client = new DiagnosticsClient(pi.EndpointInfo.Endpoint);

                    MetricsOptions options = _optionsMonitor.CurrentValue;
                    using var optionsTokenSource = new CancellationTokenSource();

                    //If metric options change, we need to cancel the existing metrics pipeline and restart with the new settings.
                    using IDisposable monitorListener = _optionsMonitor.OnChange((_, _) => optionsTokenSource.Cancel());

                    EventPipeCounterGroup[] counterGroups = Array.Empty <EventPipeCounterGroup>();
                    if (options.Providers.Count > 0)
                    {
                        //In the dotnet-monitor case, custom metrics are additive to the default counters.
                        var eventPipeCounterGroups = new List <EventPipeCounterGroup>();
                        if (options.IncludeDefaultProviders)
                        {
                            eventPipeCounterGroups.Add(new EventPipeCounterGroup {
                                ProviderName = MonitoringSourceConfiguration.SystemRuntimeEventSourceName
                            });
                            eventPipeCounterGroups.Add(new EventPipeCounterGroup {
                                ProviderName = MonitoringSourceConfiguration.MicrosoftAspNetCoreHostingEventSourceName
                            });
                            eventPipeCounterGroups.Add(new EventPipeCounterGroup {
                                ProviderName = MonitoringSourceConfiguration.GrpcAspNetCoreServer
                            });
                        }

                        foreach (MetricProvider customProvider in options.Providers)
                        {
                            var customCounterGroup = new EventPipeCounterGroup {
                                ProviderName = customProvider.ProviderName
                            };
                            if (customProvider.CounterNames.Count > 0)
                            {
                                customCounterGroup.CounterNames = customProvider.CounterNames.ToArray();
                            }
                            eventPipeCounterGroups.Add(customCounterGroup);
                        }
                        counterGroups = eventPipeCounterGroups.ToArray();
                    }

                    _counterPipeline = new EventCounterPipeline(client, new EventPipeCounterPipelineSettings
                    {
                        CounterGroups   = counterGroups,
                        Duration        = Timeout.InfiniteTimeSpan,
                        RefreshInterval = TimeSpan.FromSeconds(options.UpdateIntervalSeconds)
                    }, metricsLogger: new[] { new MetricsLogger(_store.MetricsStore) });

                    using var linkedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken, optionsTokenSource.Token);
                    await _counterPipeline.RunAsync(linkedTokenSource.Token);
                }
                catch (Exception e) when(e is not OperationCanceledException || !stoppingToken.IsCancellationRequested)
                {
                    //Most likely we failed to resolve the pid or metric configuration change. Attempt to do this again.
                    if (_counterPipeline != null)
                    {
                        await _counterPipeline.DisposeAsync();
                    }
                    await Task.Delay(5000);
                }
            }
        }