using BuildingBlocks.Core.CQRS; using BuildingBlocks.OpenTelemetryCollector.CoreDiagnostics.Commands; using BuildingBlocks.OpenTelemetryCollector.CoreDiagnostics.Query; using MediatR; namespace BuildingBlocks.OpenTelemetryCollector.Behaviors; public class ObservabilityPipelineBehavior( CommandHandlerActivity commandActivity, CommandHandlerMetrics commandMetrics, QueryHandlerActivity queryActivity, QueryHandlerMetrics queryMetrics ) : IPipelineBehavior where TRequest : IRequest where TResponse : notnull { public async Task Handle(TRequest message, RequestHandlerDelegate next, CancellationToken cancellationToken) { var isCommand = message is IQuery; var isQuery = message is ICommand; if (isCommand) { commandMetrics.StartExecuting(); } if (isQuery) { queryMetrics.StartExecuting(); } try { if (isCommand) { var commandResult = await commandActivity.Execute( async (activity, ct) => { var response = await next(); return response; }, cancellationToken ); commandMetrics.FinishExecuting(); return commandResult; } if (isQuery) { var queryResult = await queryActivity.Execute( async (activity, ct) => { var response = await next(); return response; }, cancellationToken ); queryMetrics.FinishExecuting(); return queryResult; } } catch (System.Exception) { if (isQuery) { queryMetrics.FailedCommand(); } if (isCommand) { commandMetrics.FailedCommand(); } throw; } return await next(); } }