1

I am trying to log request and response in a Middleware using ASP .Net Core and Application Insights, but Application Insights doesn't log information. My code:

RequestResponseLoggingMiddleware.cs

public class RequestResponseLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<RequestResponseLoggingMiddleware> _logger;
    private readonly RecyclableMemoryStreamManager _recyclableMemoryStreamManager;

    public RequestResponseLoggingMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
    {
        _next = next;
        _logger = loggerFactory.CreateLogger<RequestResponseLoggingMiddleware>();
        _recyclableMemoryStreamManager = new RecyclableMemoryStreamManager();
    }

    public async Task Invoke(HttpContext context)
    {
        await LogRequest(context);
        await LogResponse(context);
    }

    private async Task LogRequest(HttpContext context)
    {
        context.Request.EnableBuffering();

        await using var requestStream = _recyclableMemoryStreamManager.GetStream();
        await context.Request.Body.CopyToAsync(requestStream);
        _logger.LogInformation($"Http Request Information:{Environment.NewLine}" +
                               $"Schema:{context.Request.Scheme} " +
                               $"Host: {context.Request.Host} " +
                               $"Path: {context.Request.Path} " +
                               $"QueryString: {context.Request.QueryString} " +
                               $"Request Body: {ReadStreamInChunks(requestStream)}");
        context.Request.Body.Position = 0;
    }

    private async Task LogResponse(HttpContext context)
    {
        var originalBodyStream = context.Response.Body;

        await using var responseBody = _recyclableMemoryStreamManager.GetStream();
        context.Response.Body = responseBody;

        await _next(context);

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

        _logger.LogInformation($"Http Response Information:{Environment.NewLine}" +
                               $"Schema:{context.Request.Scheme} " +
                               $"Host: {context.Request.Host} " +
                               $"Path: {context.Request.Path} " +
                               $"QueryString: {context.Request.QueryString} " +
                               $"Response Body: {text}");

        await responseBody.CopyToAsync(originalBodyStream);
    }

    private static string ReadStreamInChunks(Stream stream)
    {
        const int readChunkBufferLength = 4096;

        stream.Seek(0, SeekOrigin.Begin);

        using var textWriter = new StringWriter();
        using var reader = new StreamReader(stream);

        var readChunk = new char[readChunkBufferLength];
        int readChunkLength;

        do
        {
            readChunkLength = reader.ReadBlock(readChunk, 0, readChunkBufferLength);
            textWriter.Write(readChunk, 0, readChunkLength);
        } while (readChunkLength > 0);

        return textWriter.ToString();
    }
}

appsettings.json

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "ApplicationInsights": {
    "LogLevel": {
      "Default": "Error"
    },
    "ConnectionString": "InstrumentationKey=deletedforskingthisquestion;IngestionEndpoint=https://centralus-0.in.applicationinsights.azure.com/"
  },

When I check my Application Insights I see that information log has not been registered. I would like to know my mistake. Thanks in advance.

4 Answers 4

2

Looks like issue with LogLevel:

Config Saying: Error

"ApplicationInsights": {
    "LogLevel": {
      "Default": "Error"
    }
  }

But when logging you are looging at LogLevel: LogInformation

private async Task LogRequest(HttpContext context) { context.Request.EnableBuffering();

await using var requestStream = _recyclableMemoryStreamManager.GetStream();
await context.Request.Body.CopyToAsync(requestStream);
_logger.LogInformation($"Http Request Information:{Environment.NewLine}" +
                       $"Schema:{context.Request.Scheme} " +
                       $"Host: {context.Request.Host} " +
                       $"Path: {context.Request.Path} " +
                       $"QueryString: {context.Request.QueryString} " +
                       $"Request Body: {ReadStreamInChunks(requestStream)}");
context.Request.Body.Position = 0;

}

Tyring to change LogLevel to "Error".

and check the following config settings at Startup class:

public partial class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddApplicationInsightsTelemetry("InstrumentationKey");
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

There're 2 mistakes in the appsettings.json file:

  1. In the "ApplicationInsights" section, change "Default": "Error" to "Default": "Information".

  2. Then put the "ApplicationInsights" section into Logging section. Like below:

       {
          "Logging": {
             "LogLevel": {
               "Default": "Information",
               "Microsoft": "Information",
               "Microsoft.Hosting.Lifetime": "Information"
             },
             "ApplicationInsights": {
               "LogLevel": {
                 "Default": "Information"
               }
             }
           },
    
         //other settings.
       }
    

2 Comments

You are right, it works!. Thank you very much. If I want to log everything, what I have to make in LogLevel?.
@OmarMurcia You should set it as Trace if you want to log everything. See Log level for more details.
1

Have you included NLogger Application Insights package to your project?

Try adding this to your project: https://www.nuget.org/packages/Microsoft.Extensions.Logging.ApplicationInsights/ (see this for ref.)

You could also change the LogLevel on your ApplicationInsights settings as now it seems to collect only Error level when in your application you are logging in Information level. You could try changing that to i.e. Debug like this:

...
"ApplicationInsights": {
  "LogLevel": {
    "Default": "Debug"
  },
...

Comments

1

Your specified configuration applies the log filtering for ApplicationInsightsLoggerProvider, the provider alias is ApplicationInsights. The default log level is information but for provider ApplicationInsights it is override to Error level

"Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    },
   "ApplicationInsights": {
    "LogLevel": {
      "Default": "Error"
    }
  }

To fix, you can change the ApplicationInsights default's log level to Informatio and move ApplicationInsights into Logging section.

"ApplicationInsights": {
  "LogLevel": {
   "Default": "Information"
 }

Read Control logging level.

Another point here, you are creating a new log entry to log the request's request and response details/body. As such you don't need a new log entry, you can update the details in the existing request telemetry. You can refer the code mentioned at this repo which can be extended further to log the other details and also it provides the capability of removing the sensitive information during logging of request body (which can be extended for response body).

3 Comments

I tried that, but it doesn't work. The information log is not registered yet.
I missed that but as mentioned by Ivan, the config section need to be updated to move ApplicationInsights into Logging section. Also, did you check the other point mentioned I've mentioned to use the Request telemetry log instead of creating a new one?
Yes my friend, you are right. Thank you very much. I really appreciate it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.