AndrewSilver
AndrewSilver

Reputation: 1163

Change logging verbosity level for health check endpoint in ASP.NET Core application

I have an ASP.NET Core application (.NET 5 actually) and it has health check endpoints implemented in a standard way with

services.AddHealthChecks()...

Health checks are working fine. The problem is they are being invoked quite often and hence they generate a lot of logs in our storage.

Service has standard .NET logging mechanisms and defaults in appsettings.json like

  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Debug"
    }
  },

The question is how can I change verbosity level (to Information, for example) for this very heath check (and its implementation inside also, like EF.Core stuff or anything else) while keeping it as Debug in all other places? Are there any parameters or settings to help with this?

The goal here is to reduce logging storage consumption.

Upvotes: 5

Views: 9172

Answers (2)

Sam Byng
Sam Byng

Reputation: 21

I achieved this with a combination of:

  1. @Pablo Recalde's changes to the appsettings.json (to filter out specific logs > Warning produced regularly by certain librarys)

  2. Where normal app service code is called (that will be used in regular calling paths), use a NullLogger:

Note: Logically, this doesn't stop all logging paths + is a bit whack-a-mole but works to remove the majority of the logs produced during 'normal/success' health check scenarios.

implementation: 1.:

  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.Identity": "Warning"
    },
    "AzureAppServicesFile": {
      "LogLevel": {
        "Default": "Trace",
        "Microsoft.AspNetCore": "Warning",
        "Microsoft.Identity": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "LogLevel": {
        "Default": "Trace",
        "Microsoft.AspNetCore": "Warning",
        "Microsoft.Identity": "Warning"
      }
    }
  },
    public async Task MyFunctionName(bool useNullLogger) {

        if (useNullLogger)
        {
            _logger = new NullLogger<MyClassName>();
        }
...
}

Upvotes: 2

Pablo Recalde
Pablo Recalde

Reputation: 3571

In the settings file:

"Logging": {
  "LogLevel": {
    "Default": "Debug",
    "Microsoft": "Debug",
    "Microsoft.Hosting.Lifetime": "Debug"
  }
},

You can configure the LogLevel on the namespace level by specifiying "namespace":"LogLevel" inside the LogLevel configuration object.

For instance:

You're seeing lots of dbug: Microsoft.EntityFrameworkCore.Database.Connection[20000] Opening connection to database 'some_db' on server 'tcp://localhost:5432' messages.

As you can tell by the line itself, they're coming from Microsoft.EntityFrameworkCore.Database.Connection object, inside Microsoft.EntityFrameworkCore.Database namespace.

So you could modify the LogLevel for Microsoft, or Microsoft.EntityFrameworkCore or even Microsoft.EntityFrameworkCore.Database namespace to be Information for instance:

"Logging": {
  "LogLevel": {
    "Default": "Debug",
    "Microsoft": "Debug",
    "Microsoft.Hosting.Lifetime": "Debug",
    "Microsoft.EntityFrameworkCore.Database": "Information"
  }
},

Now the line dbug: Microsoft.EntityFrameworkCore.Database.Connection[20000] Opening connection to database 'some_db' on server 'tcp://localhost:5432' won't get logged because its level is Debug and the minimum threshold is configured to be Information.

EDIT

It looks like you're trying to filter based on the context of the request instead of using just the namespace.

AFAIK, aspnetcore logging package is not capable of doing that. On the other hand, Serilog with a little aid from Serilog.Expressions can filter out the log messages when they originated from specific requests.

From Serilog.Expressions readme file:

Filtering example

Serilog.Expressions adds ByExcluding() and ByIncludingOnly() overloads to the Filter configuration object that accept filter expressions:

Log.Logger = new LoggerConfiguration()
 .Filter.ByExcluding("RequestPath like '/health%'")
 .CreateLogger();

Upvotes: 3

Related Questions