public Task <ActionResult> CaptureMetricsCustom( [FromBody][Required] Models.EventMetricsConfiguration configuration, [FromQuery] int?pid = null, [FromQuery] Guid?uid = null, [FromQuery] string name = null, [FromQuery][Range(-1, int.MaxValue)] int durationSeconds = 30, [FromQuery] string egressProvider = null) { ProcessKey?processKey = GetProcessKey(pid, uid, name); return(InvokeForProcess(async(processInfo) => { string fileName = GetMetricFilename(processInfo); Func <Stream, CancellationToken, Task> action = async(outputStream, token) => { var client = new DiagnosticsClient(processInfo.EndpointInfo.Endpoint); EventPipeCounterPipelineSettings settings = EventCounterSettingsFactory.CreateSettings( _counterOptions.CurrentValue, durationSeconds, configuration); await using EventCounterPipeline eventCounterPipeline = new EventCounterPipeline(client, settings, loggers: new[] { new JsonCounterLogger(outputStream) }); await eventCounterPipeline.RunAsync(token); }; return await Result(Utilities.ArtifactType_Metrics, egressProvider, action, fileName, ContentTypes.ApplicationJsonSequence, processInfo.EndpointInfo); }, processKey, Utilities.ArtifactType_Metrics)); }
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); } } }