Search code examples
c#asp.netloggingswagger.net-7.0

Is there a way to ignore swagger response in HTTP Logging in ASP.NET Core?


I have a asp.net web api that is created with .net 7.

I enabled http logging to see the complete http request and responses in the logs of the application. (I am aware that it could contain sensitive information, but with the nature of the application, this should not be a problem).

The Http Logging is working like expected, with the exception of one oversight on my part. Swagger responses are also being logged now. Thus every time I navigate to my swagger endpoint, it fills my logs with the swagger HTML the swagger json. Things like this:

Connection: keep-alive
Host: localhost:7122
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en
Cookie: [Redacted]
Upgrade-Insecure-Requests: [Redacted]
Sec-GPC: [Redacted]
Sec-Fetch-Site: [Redacted]
Sec-Fetch-Mode: [Redacted]
Sec-Fetch-User: [Redacted]
Sec-Fetch-Dest: [Redacted]
sec-ch-ua: [Redacted]
sec-ch-ua-mobile: [Redacted]
sec-ch-ua-platform: [Redacted]
[14:55:42 INF] Response:
StatusCode: 200
Content-Type: text/html;charset=utf-8
[14:55:42 INF] ResponseBody: <!-- HTML for static distribution bundle build -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css">
    <link rel="icon" type="image/png" href="./favicon-32x32.png" sizes="32x32" />
    <link rel="icon" type="image/png" href="./favicon-16x16.png" sizes="16x16" />
    <style>

        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }

        *,
        *:before,
        *:after {
            box-sizing: inherit;
        }

        body {
            margin: 0;
            background: #fafafa;
        }
    </style>
    
</head>

<body>
    <div id="swagger-ui"></div>

    <!-- Workaround for https://github.com/swagger-api/swagger-editor/issues/1371 -->
    <script>

...
/// Rest left out because I think you get the point...

It is not a major issue as it will most likely not flood the logs when it is in production, as it won't be the main request being triggered by the application all the time, but during development it is something that is being used quite a lot and it is a bit irritating because it does end up filling up the logs with info that is not that crucial to me at the moment.

While reading through the link about the HttpLogging , I did see that I can filter out MediaTypeOptions. Since I only have a web api, I don't need anything other than application/json so I thought I would filter out everything except that:

services
.AddHttpLogging(options =>
{
  options.LoggingFields = HttpLoggingFields.All;
  options.RequestBodyLogLimit = 4096;
  options.ResponseBodyLogLimit = 4096;
  options.MediaTypeOptions.Clear();
  options.MediaTypeOptions.AddText("application/json");
})

But that does not seem to work. I am still stuck with swagger output in my logs.

To be clear, I don't want to ignore swagger requests completely, I just want to ignore them being logged in my httpLogging.

Is there an easy way to filter out the swagger from my HttpLogging?

Any help would be greatly appreciated.


Solution

  • Do not know why this does happen (seems like a bit misleading documentation or a bug to me, will investigate later) but there are at least 2 workarounds:

    1. Call UseHttpLogging() after the swagger:

      app.UseSwagger();
      app.UseSwaggerUI();
      app.UseHttpLogging();
      
    2. Use conditionals:

      app.UseWhen(ctx => !ctx.Request.Path.StartsWithSegments("/swagger"), // assuming default swagger path, if not - adjust accrodingly
       appBuilder => appBuilder.UseHttpLogging());
      

    UPD

    Another way to handle things is using the IHttpLoggingInterceptor:

    builder.Services.AddHttpLoggingInterceptor<CustomHttpLoggingInterceptor>();
    
    class CustomHttpLoggingInterceptor : IHttpLoggingInterceptor
    {
        public ValueTask OnRequestAsync(HttpLoggingInterceptorContext logContext)
        {
            if (logContext.HttpContext.Request.Path.StartsWithSegments("/swagger"))
            {
                logContext.LoggingFields = HttpLoggingFields.None;
            }
    
            return ValueTask.CompletedTask;
        }
    
        public ValueTask OnResponseAsync(HttpLoggingInterceptorContext logContext) => ValueTask.CompletedTask;
    }