awslabs / aws-embedded-metrics-dotnet

Amazon CloudWatch Embedded Metric Format Client Library
Apache License 2.0
22 stars 14 forks source link

UseEmfMiddleware middleware allocates a new Stopwatch instance every request #61

Open phalvesr opened 1 month ago

phalvesr commented 1 month ago

After taking a closer look at the UseEmfMiddleware - middleware responsable for measuring the time a request takes to be completed - I could notice that it is instanciating a new Stopwatch every request. As it can lead to potential performance issues in scenarios where the api is called hundreds or thousands of times I propose a change to use something like the ValueStopwatch struct used by the dotnet team to measure time without allocating a new object on the heap. I have already implemented those change on the PR #60 - Changes UseEmfMiddleware to avoid allocating a new stopwatch instance per request.

Middleware code as it is now:

public static void UseEmfMiddleware(this IApplicationBuilder app, Func<HttpContext, IMetricsLogger, Task> action)
{
    app.Use(async (context, next) =>
    {
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();
        await next.Invoke();
        var config = context.RequestServices.GetRequiredService<EMF.Config.IConfiguration>();
        var logger = context.RequestServices.GetRequiredService<IMetricsLogger>();

        if (!String.IsNullOrEmpty(config.ServiceName))
        {
            logger.SetNamespace(config.ServiceName);
        }

        await action(context, logger);
        stopWatch.Stop();
        logger.PutMetric("Time", stopWatch.ElapsedMilliseconds, Model.Unit.MILLISECONDS);
    });
}