From 92be035f51ad6485da92ee0e2aaafd0db0f1954e Mon Sep 17 00:00:00 2001 From: Anatolii Grynchuk Date: Sat, 2 May 2026 01:15:10 +0300 Subject: [PATCH] feat: replace manual Stopwatch with IProfiler in TransactionBehavior - Add HrynCo.Common to Services project - TransactionBehavior now uses IProfiler.MeasureExecutionAsync: MeasureExecutionAsync -> ExecuteInTransactionAsync -> next() -> SaveChangesAsync - Profiler logs Start/End with duration + memory delta via Serilog PerformanceLog context - Register IProfiler as singleton in ServiceCollectionExtensions (uses Log.Logger) Ref: IT-628 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Directory.Packages.props | 1 + .../Behaviors/TransactionBehavior.cs | 34 +++++-------------- .../Core/RequestHandler.cs | 8 +++-- ...HrynCo.NotificationService.Services.csproj | 1 + .../ServiceCollectionExtensions.cs | 3 ++ 5 files changed, 19 insertions(+), 28 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 709c83d..fbf8429 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -27,6 +27,7 @@ + diff --git a/HrynCo.NotificationService.Services/Behaviors/TransactionBehavior.cs b/HrynCo.NotificationService.Services/Behaviors/TransactionBehavior.cs index dfe96ac..db7592a 100644 --- a/HrynCo.NotificationService.Services/Behaviors/TransactionBehavior.cs +++ b/HrynCo.NotificationService.Services/Behaviors/TransactionBehavior.cs @@ -1,7 +1,6 @@ -using System.Diagnostics; +using HrynCo.Common; using HrynCo.NotificationService.DAL.Abstract; using MediatR; -using Microsoft.Extensions.Logging; namespace HrynCo.NotificationService.Services.Behaviors; @@ -9,36 +8,21 @@ public class TransactionBehavior : IPipelineBehavior> _logger; + private readonly IProfiler _profiler; - public TransactionBehavior(IUnitOfWork unitOfWork, ILogger> logger) + public TransactionBehavior(IUnitOfWork unitOfWork, IProfiler profiler) { _unitOfWork = unitOfWork; - _logger = logger; + _profiler = profiler; } - public async Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) - { - string handlerName = typeof(TRequest).Name; - _logger.LogDebug("Handling {Handler}", handlerName); - - Stopwatch sw = Stopwatch.StartNew(); - try - { - TResponse result = await _unitOfWork.ExecuteInTransactionAsync(async () => + public Task Handle(TRequest request, RequestHandlerDelegate next, CancellationToken cancellationToken) => + _profiler.MeasureExecutionAsync( + () => _unitOfWork.ExecuteInTransactionAsync(async () => { TResponse response = await next(); await _unitOfWork.SaveChangesAsync(cancellationToken); return response; - }); - - _logger.LogDebug("Handled {Handler} in {ElapsedMs}ms", handlerName, sw.ElapsedMilliseconds); - return result; - } - catch (Exception ex) - { - _logger.LogError(ex, "Handler {Handler} failed after {ElapsedMs}ms", handlerName, sw.ElapsedMilliseconds); - throw; - } - } + }), + typeof(TRequest).Name); } \ No newline at end of file diff --git a/HrynCo.NotificationService.Services/Core/RequestHandler.cs b/HrynCo.NotificationService.Services/Core/RequestHandler.cs index d48a483..b40264e 100644 --- a/HrynCo.NotificationService.Services/Core/RequestHandler.cs +++ b/HrynCo.NotificationService.Services/Core/RequestHandler.cs @@ -17,8 +17,10 @@ public abstract class RequestHandler : IRequestHandler Handle(TRequest request, CancellationToken cancellationToken) => - DoOnHandle(request, cancellationToken); + public Task Handle(TRequest request, CancellationToken cancellationToken) + { + return DoOnHandle(request, cancellationToken); + } protected abstract Task DoOnHandle(TRequest request, CancellationToken cancellationToken); -} +} \ No newline at end of file diff --git a/HrynCo.NotificationService.Services/HrynCo.NotificationService.Services.csproj b/HrynCo.NotificationService.Services/HrynCo.NotificationService.Services.csproj index d7539ee..7cb964d 100644 --- a/HrynCo.NotificationService.Services/HrynCo.NotificationService.Services.csproj +++ b/HrynCo.NotificationService.Services/HrynCo.NotificationService.Services.csproj @@ -1,6 +1,7 @@  + diff --git a/HrynCo.NotificationService.Services/ServiceCollectionExtensions.cs b/HrynCo.NotificationService.Services/ServiceCollectionExtensions.cs index f49dfdd..da4019c 100644 --- a/HrynCo.NotificationService.Services/ServiceCollectionExtensions.cs +++ b/HrynCo.NotificationService.Services/ServiceCollectionExtensions.cs @@ -1,7 +1,9 @@ +using HrynCo.Common; using HrynCo.NotificationService.Services.Behaviors; using HrynCo.NotificationService.Services.Logging; using MediatR; using Microsoft.Extensions.DependencyInjection; +using Serilog; namespace HrynCo.NotificationService.Services; @@ -16,6 +18,7 @@ public static class ServiceCollectionExtensions }); services.AddTransient(typeof(IContextualSerilogLogger<>), typeof(ContextualSerilogLogger<>)); + services.AddSingleton(new Profiler(Log.Logger)); return services; }