internal async Task OnResponseCompleted(HttpContext httpContext, IServerTiming serverTiming, IReadOnlyList <IServerTimingCallback> callbacks) { var metrics = serverTiming.GetMetrics(); var timingEvent = new ServerTimingEvent(httpContext, metrics); var tasks = new Task[callbacks.Count]; for (var i = 0; i < callbacks.Count; i++) { tasks[i] = callbacks[i].OnServerTiming(timingEvent); } var aggregationTask = Task.WhenAll(tasks); try { await aggregationTask; } // ReSharper disable once EmptyGeneralCatchClause catch (Exception) { // AggregateException will be available below with exceptions from all tasks. } if (aggregationTask.Exception == null) { return; } var innerExceptions = aggregationTask.Exception.InnerExceptions; // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < innerExceptions.Count; i++) { _logger.LogError(innerExceptions[i], "Exception was thrown invoking Server Timing callback"); } }
internal Task OnResponseStarting(HttpContext httpContext, IManualMetric totalMetric, IServerTiming serverTiming, RequestTimingOptions requestOptions) { totalMetric.Stop(); var metrics = serverTiming.GetMetrics(); if (_options.ValidateMetrics && httpContext.Response.StatusCode != 500) { // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < metrics.Count; i++) { if (metrics[i] is IValidatableMetric validatableMetric) { if (!validatableMetric.Validate(out var message)) { _logger.LogWarning(message); } } } } if (!requestOptions.WriteHeader) { return(Task.CompletedTask); } if (!requestOptions.IncludeCustomMetrics) { metrics = new[] { (IMetric)totalMetric } } ; _headerWriter.WriteHeaders(httpContext.Response.Headers, requestOptions.IncludeDescriptions, metrics); return(Task.CompletedTask); }