public async Task EvaluateAsync(MetricQuery query, CancellationToken cancellation = default) { var options = _optionsProvider.Value; var timeout = query.Timeout.GetValueOrDefault(options.Metrics.Evaluation.Timeout); var interval = query.Interval.GetValueOrDefault(options.Metrics.Evaluation.Interval); try { _logger.LogInformation("Starting evaluation of query '{Query}'", query.Name); var result = await _queryExecutor.ExecuteAsync(query, timeout, cancellation); await _metricsWriter.WriteAsync(query, result, cancellation); } catch (Exception e) { _logger.LogError(e, "Query '{Query}' evaluation failed with exception", query.Name); } finally { _logger.LogInformation("Query '{Query}' evaluated. Next evaluation on '{NextOccurence}'", query.Name, (DateTime.Now + interval)); // Re-schedule _jobClient.Schedule <ScheduledMetricsEvaluator>( e => e.EvaluateAsync(query, cancellation), interval); } }
public async Task Invoke(HttpContext context, IMetricQueriesProvider queriesProvider, IOptions <ExporterOptions> optionsProvider, IMetricQueryExecutor queryExecutor, IMetricsWriter metricsWriter, ILogger <OndemandMetricsEvaluationMiddleware> logger) { var options = optionsProvider.Value; var defaultMode = options.Metrics.Evaluation.Mode; var queries = await queriesProvider.GetAsync(context.RequestAborted); var tasks = queries.Select(q => { if (q.EvaluationMode == MetricsEvaluationMode.Scheduled) { return(Task.CompletedTask); } if (!q.EvaluationMode.HasValue && defaultMode == MetricsEvaluationMode.Scheduled) { return(Task.CompletedTask); } return(Task.Run(async() => { try { logger.LogInformation($"Executing on-demand query '{q.Name}'"); var timeout = q.Timeout.GetValueOrDefault(options.Metrics.Evaluation.Timeout); var result = await queryExecutor.ExecuteAsync(q, timeout, context.RequestAborted); await metricsWriter.WriteAsync(q, result, context.RequestAborted); logger.LogInformation($"Executed on-demand query '{q.Name}'"); } catch (OperationCanceledException) { // Ignore } catch (Exception e) { logger.LogError(e, $"Unable to write metric for query '{q.Name}'"); } }, context.RequestAborted)); }); await Task.WhenAll(tasks); await _next(context); }