Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure .net core logging to log request and response

I'm developing asp .net core 2.1 WEB-API application.

I use ILogger with configuration:

"Logging": {
"LogLevel": {
  "Default": "Debug",
  "System": "Information",
  "Microsoft": "Information"
}

And on request i see log:

info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1] Executing action method ActivationService.Controllers.ActivationController.Post (ActivationService) with arguments (ActivationService.Contracts.ActivationRequest) - Validation state: Valid

and

Executed action method ActivationService.Controllers.ActivationController.Post (ActivationService), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 174605.9201ms.

Is there way to confugure asp.net to log with trace body of response and request?

like image 962
Timur Lemeshko Avatar asked Jul 12 '18 12:07

Timur Lemeshko


1 Answers

Yes, you can implement logging middleware:

public class RequestResponseLoggingMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILogger logger;

        public RequestResponseLoggingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
        {
            this.next = next;
            logger = loggerFactory.CreateLogger<RequestResponseLoggingMiddleware>();
        }

        public async Task Invoke(HttpContext context)
        {
            context.Request.EnableRewind();

            var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)];
            await context.Request.Body.ReadAsync(buffer, 0, buffer.Length);
            var requestBody = Encoding.UTF8.GetString(buffer);
            context.Request.Body.Seek(0, SeekOrigin.Begin);

            logger.LogInformation(requestBody);

            var originalBodyStream = context.Response.Body;

            using (var responseBody = new MemoryStream())
            {
                context.Response.Body = responseBody;

                await next(context);

                context.Response.Body.Seek(0, SeekOrigin.Begin);
                var response = await new StreamReader(context.Response.Body).ReadToEndAsync();
                context.Response.Body.Seek(0, SeekOrigin.Begin);

                logger.LogInformation(response);
                await responseBody.CopyToAsync(originalBodyStream);
            }
        }
    }

And then add it to application Builder in Configure method:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ....
    app.UseMiddleware<RequestResponseLoggingMiddleware>();
}
like image 154
Alex Riabov Avatar answered Oct 19 '22 00:10

Alex Riabov