LoggingBehavior.cs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. using System.Diagnostics;
  2. using MediatR;
  3. using Microsoft.Extensions.Logging;
  4. namespace Application.Behaviors;
  5. public sealed class LoggingBehavior<TRequest, TResponse>(ILogger<LoggingBehavior<TRequest, TResponse>> logger) : IPipelineBehavior<TRequest, TResponse> where TRequest : notnull
  6. {
  7. private const long SlowThresholdMs = 500;
  8. public async Task<TResponse> Handle(
  9. TRequest request,
  10. RequestHandlerDelegate<TResponse> next,
  11. CancellationToken ct
  12. ) {
  13. var requestName = typeof(TRequest).Name;
  14. var sw = Stopwatch.StartNew();
  15. try
  16. {
  17. var result = await next(ct);
  18. sw.Stop();
  19. if (sw.ElapsedMilliseconds > SlowThresholdMs)
  20. {
  21. logger.LogWarning("[Slow] {Request} took {Elapsed}ms", requestName, sw.ElapsedMilliseconds);
  22. }
  23. else if (logger.IsEnabled(LogLevel.Debug))
  24. {
  25. logger.LogDebug("[Done] {Request} {Elapsed}ms", requestName, sw.ElapsedMilliseconds);
  26. }
  27. return result;
  28. }
  29. catch (Exception ex)
  30. {
  31. sw.Stop();
  32. logger.LogError(ex, "[Failed] {Request} after {Elapsed}ms", requestName, sw.ElapsedMilliseconds);
  33. throw;
  34. }
  35. }
  36. }