Skip to content

Instantly share code, notes, and snippets.

@dustinsoftware
Last active November 30, 2022 21:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustinsoftware/e4dbffa204d7ce42ad4b8110ece15f16 to your computer and use it in GitHub Desktop.
Save dustinsoftware/e4dbffa204d7ce42ad4b8110ece15f16 to your computer and use it in GitHub Desktop.

Advanced http logging in Kestrel

(This post is for https://dotnet.christmas/)

.NET can run on Linux now!

This is old news, you might say to yourself. However, when porting apps that were previously running in IIS, you may have been relying on this logging feature:

image

Which logs HTTP requests in a format that looks like this:

#Software: Microsoft Internet Information Services 10.0
#Version: 1.0
#Date: 2022-10-27 17:30:19
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) cs(Referer) sc-status sc-substatus sc-win32-status time-taken
2022-10-27 17:30:19 127.0.0.1 GET / - 5091 - 127.0.0.1 curl/7.83.1 - 200 0 64 63699
2022-10-27 17:30:31 127.0.0.1 GET /api/healthcheck - 5091 - 127.0.0.1 curl/7.83.1 - 200 0 0 13507
2022-10-27 17:30:44 127.0.0.1 GET /api/healthcheck - 5091 - 127.0.0.1 curl/7.83.1 - 200 0 0 53
2022-10-27 17:30:47 127.0.0.1 GET /api/healthcheck - 5091 - 127.0.0.1 curl/7.83.1 - 200 0 0 314

Up until .NET 6, you had to write middleware to do this yourself - now, this is built in to the ASP.NET runtime!

It’s as simple as calling builder.Services.AddW3CLogging(_ => {}); followed by app.UseW3CLogging();

Now, each request that comes in will get logged to disk in the logs folder of your app's content directory, including status codes and client IP addresses.

image

But did you also know in .NET 7 you can log additional request headers? IIS had this capability under the "Select Fields" page:

image

Maybe you’re using a reverse proxy that sends the X-Forwarded-For header. Or, you’re sending a custom client version in the My-Cool-App-Version header.

You can log those too! Just specify the AdditionalRequestHeaders property.

builder.Services.AddW3CLogging(options =>
{
    options.AdditionalRequestHeaders.Add("x-forwarded-for");
    options.AdditionalRequestHeaders.Add("my-cool-app-version");
});

Voila!

image

But, what if we need to change those without an app deploy?

Let’s move that into config files and bind them:

builder.Services.AddW3CLogging(options =>
{
    builder.Configuration.GetSection("W3CLoggerOptions").Bind(options);
});

And, in appsettings.json:

  "W3CLoggerOptions": {
    "AdditionalRequestHeaders": ["x-forwarded-for", "my-cool-app-version"]
  }

Now, you can adjust the logging settings without a recompile, such as during app deployment using a different configuration for staging and live environments.

There are other options you can configure as well, such as the LogDirectory. However, note that AdditionalRequestHeaders is only available on .NET 7 at this time, although you could backport the logging code to run on .NET 6 (which is the current LTS).

That's it, happy logging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment