/Nefarius.Utilities.AspNetCore

My opinionated collection of utilities for ASP.NET Core applications.

Primary LanguageC#MIT LicenseMIT

Nefarius.Utilities.AspNetCore

GitHub Workflow Status Requirements Nuget Nuget

My opinionated collection of utilities for ASP.NET Core applications.

Features

  • Sets up application (and optionally web requests) logging with Serilog
  • Sets up application log file rotation and compression
  • Sets up W3C logging to a separate access log file
    • Compresses rolled W3C log files and allows for their own retention settings
  • Sets up forwarded headers and auto-configures local networks so the correct client IP ends up in logs and middleware
    • ⚠️ This assumes that your app sits behind a reverse proxy, do not enable this setting if your app faces the Internet directly or header spoofing becomes possible!
  • ... and more as I start incorporating this lib in my projects!

How to use

Replace 👇

WebApplicationBuilder builder = WebApplication.CreateBuilder(args);

with 👇

WebApplicationBuilder builder = WebApplication.CreateBuilder(args).Setup();

and 👇

WebApplication app = builder.Build();

with 👇

WebApplication app = builder.Build().Setup();

and you're all set! 👏 The Setup extension methods take optional configuration arguments you can provide to alter the default behaviour.

Loading additional configuration

Let's assume you have a custom /app/secrets/appsettings.json file adding one or more additional sinks (MongoDB in this example):

{
  "Serilog": {
    "Using": [
      "Serilog.Sinks.MongoDB"
    ],
    "WriteTo": [
      {
        "Name": "MongoDBBson",
        "Args": {
          "databaseUrl": "mongodb+srv://db-cluster/database?authSource=admin",
          "collectionName": "logs",
          "cappedMaxSizeMb": "1024",
          "cappedMaxDocuments": "50000",
          "rollingInterval": "Month"
        }
      }
    ]
  }
}

To have this configuration file read/merged you can access and modify the Configuration of the WebApplicationBuilderOptions like so:

WebApplicationBuilder builder = WebApplication.CreateBuilder(args).Setup(opts =>
{
    // loads settings from K8s secret
    opts.Configuration.AddJsonFile("secrets/appsettings.json", optional: true);
});

This ensures that the Serilog sinks configuration is read early enough when the logger is created.

Example configurations

From code

Enable and customize W3C log compression

The following settings use the library defaults, they're simply explained here and don't need to be exclusively set if you're satisfied with the defaults 😉

var builder = WebApplication.CreateBuilder().Setup(options =>
{
    // this will only keep three most recent uncompressed log files
    options.W3C.RetainedFileCountLimit = 3;
    // on rotation, make a compressed archive copy before deleting the original
    options.W3C.CompressDeletedLogFiles = true;
    // keeps the last 90 compressed log files on top of the original files
    // after this, even the compressed logs are finally deleted from disk
    options.W3C.RetainedCompressedFileCountLimit = 90;
});

From appsettings.json

You can also alter the defaults from your configuration; simply stick to the options classes and property naming conventions like so:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "WebApplicationBuilderOptions": {
    "AutoDetectPrivateNetworks": false
  },
  "WebApplicationOptions": {
    "UseForwardedHeaders": false
  }
}

Bear in mind that changing the same option in code will take priority over application configuration.

From docker-compose.yml

Using this format you can change the settings directly in the compose file:

...
    environment:
      - TZ=Europe/Vienna
      - WebApplicationBuilderOptions__W3C__RetainedCompressedFileCountLimit=600
      - WebApplicationBuilderOptions__W3C__RetainedFileCountLimit=12
...

3rd party credits