public async Task Invoke(HttpContext context) { if (context.Request.Path.HasValue && context.Request.Path.StartsWithSegments(FhirServerApplicationBuilderExtensions.HealthCheckPath, System.StringComparison.InvariantCultureIgnoreCase)) { // Don't emit events for health check await _next(context); return; } var apiNotification = new ApiResponseNotification(); using (var timer = _logger.BeginTimedScope("ApiNotificationMiddleware") as ActionTimer) { try { await _next(context); } finally { apiNotification.Latency = timer.GetElapsedTime(); try { IFhirRequestContext fhirRequestContext = _fhirRequestContextAccessor.FhirRequestContext; // For now, we will only emit metrics for audited actions (e.g., metadata will not emit metrics). if (fhirRequestContext?.AuditEventType != null) { apiNotification.Authentication = fhirRequestContext.Principal?.Identity.AuthenticationType; apiNotification.FhirOperation = fhirRequestContext.AuditEventType; apiNotification.Protocol = context.Request.Scheme; apiNotification.ResourceType = fhirRequestContext.ResourceType; apiNotification.StatusCode = (HttpStatusCode)context.Response.StatusCode; await _mediator.Publish(apiNotification, CancellationToken.None); if (fhirRequestContext.StorageRequestMetrics != null) { await _mediator.Publish(fhirRequestContext.StorageRequestMetrics, CancellationToken.None); } } } catch (Exception e) { // Failures in publishing API notifications should not cause the API to return an error. _logger.LogCritical(e, "Failure while publishing API notification."); } } } }
protected virtual async Task PublishNotificationAsync(HttpContext context, RequestDelegate next) { var apiNotification = new ApiResponseNotification(); using (var timer = _logger.BeginTimedScope(nameof(ApiNotificationMiddleware)) as ActionTimer) { try { await next(context); } finally { apiNotification.Latency = timer.GetElapsedTime(); try { IFhirRequestContext fhirRequestContext = _fhirRequestContextAccessor.FhirRequestContext; // For now, we will only emit metrics for audited actions (e.g., metadata will not emit metrics). // if (fhirRequestContext?.AuditEventType != null) // { apiNotification.Authentication = fhirRequestContext.Principal?.Identity.AuthenticationType; apiNotification.FhirOperation = fhirRequestContext.AuditEventType; apiNotification.Protocol = context.Request.Scheme; apiNotification.ResourceType = fhirRequestContext.ResourceType; apiNotification.StatusCode = (HttpStatusCode)context.Response.StatusCode; await _mediator.Publish(apiNotification, CancellationToken.None); // } } catch (Exception e) { // Failures in publishing API notifications should not cause the API to return an error. _logger.LogCritical(e, "Failure while publishing API notification."); } } } }