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)); }
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(); } }
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)); }
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); })); }
public Task <ActionResult <ProcessModel> > GetProcess( ProcessFilter processFilter) { return(this.InvokeService <ProcessModel>(async() => { IProcessInfo processInfo = await _diagnosticServices.GetProcessAsync( processFilter, HttpContext.RequestAborted); return ProcessModel.FromProcessInfo(processInfo); })); }
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)); }
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); } } }
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); } } }