using System.Diagnostics; using EventFlow.Aggregates; using EventFlow.Core; using EventFlow.Subscribers; namespace Books.Api.Logging; public class SubscribeAsynchronousToDecorator( ISubscribeAsynchronousTo inner, ILogger> logger) : ISubscribeAsynchronousTo where TAggregate : IAggregateRoot where TIdentity : IIdentity where TEvent : IAggregateEvent { public async Task HandleAsync( IDomainEvent domainEvent, CancellationToken cancellationToken) { var eventName = typeof(TEvent).Name; var handlerName = inner.GetType().Name; var aggregateId = domainEvent.AggregateIdentity.Value; logger.LogDebug( "Handling {EventName} for {AggregateId} with {HandlerName}", eventName, aggregateId, handlerName); var stopwatch = Stopwatch.StartNew(); try { await inner.HandleAsync(domainEvent, cancellationToken); stopwatch.Stop(); logger.LogInformation( "Handled {EventName} for {AggregateId} with {HandlerName} in {ElapsedMs}ms", eventName, aggregateId, handlerName, stopwatch.ElapsedMilliseconds); } catch (Exception ex) { stopwatch.Stop(); logger.LogError(ex, "Failed to handle {EventName} for {AggregateId} with {HandlerName} after {ElapsedMs}ms", eventName, aggregateId, handlerName, stopwatch.ElapsedMilliseconds); throw; } } }