books/backend/Books.Api/Logging/SubscribeAsynchronousToDecorator.cs

49 lines
1.7 KiB
C#
Raw Normal View History

using System.Diagnostics;
using EventFlow.Aggregates;
using EventFlow.Core;
using EventFlow.Subscribers;
namespace Books.Api.Logging;
public class SubscribeAsynchronousToDecorator<TAggregate, TIdentity, TEvent>(
ISubscribeAsynchronousTo<TAggregate, TIdentity, TEvent> inner,
ILogger<SubscribeAsynchronousToDecorator<TAggregate, TIdentity, TEvent>> logger)
: ISubscribeAsynchronousTo<TAggregate, TIdentity, TEvent>
where TAggregate : IAggregateRoot<TIdentity>
where TIdentity : IIdentity
where TEvent : IAggregateEvent<TAggregate, TIdentity>
{
public async Task HandleAsync(
IDomainEvent<TAggregate, TIdentity, TEvent> 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;
}
}
}