asp.net-mvcserilogserilog-exceptions

is there a way to overwrite Serilog global logger's log level


the scenario I want is to set the global log level to Error. this is my config code which is called in startup class:

 Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Error()
            .WriteTo.Logger(p=>p.Filter.ByIncludingOnly(evt => evt.Level == 
 LogEventLevel.Error).WriteTo.MSSqlServer(ConnectionString, "Serilogs",
                null, LogEventLevel.Error, 50,
                null, null, false, columnOptions))

but the thing is that I want to write some custom Information log in some of my action methods in controllers, like this:

            Log.Logger.Information("{User} {RawUrl} ", 
      userId,actionContext.Request.RequestUri.AbsolutePath);

the problem is that Serilog does not write info logs to SQL table because of the global Error level setting which is defined in startup.cs class. is there any solution for this problem (without setting the global log level to Information)?


Solution

  • The MinimumLevel.Error() construct is intended to be a coarse high level filter which can extremely efficiently rule out logging way before it makes it to a sink. While its natural to want to lean on that, its not critical - you'll be surprised how efficient Serilog will still be if you filter via whitelisting log entries later in the logging pipeline.

    WriteTo.Logger and other sinks also provide an equivalent way to set the min level that will go to that sink. The key is to thus only do the filtering at that level (with a minimumLevel optional argument override).

    Once you've removed the global filtering, which, by design, is blocking your log request from even getting captured, much less being submitted to the sinks, the next step is to have a way for your Filter.ByIncluding to identify some LogEvent's of Information level as being relevant - one example way is to whitelist particular contexts (but you might also just want to tag it with a property). Example:

    Log.Logger = ....
    
    var importantInfoLog = Log.Logger.ForContext<MyClass>();
    
    importantInfoLog.Information("Warning, this is important Information!")
    

    Then you can tell the WriteTo.Logger to

    An alternate (but in my opinion inferior) solution is to configure multiple WriteTo.Logger:-

    1. with minimumLevel set to Error
    2. the other with minimumLevel left as the default (implying >= Information) but grabbing solely the specific Information level messages that you want.