Search code examples
c#serilog

Serilog filter by method name


I'm wondering if it is possible to achieve a filtering where we improve the filtering for serilog to be more specific for sublogger. Currently I can filter the namespace, however I wanted to reach only one method in specific namespace to be logged to email, the rest methods of this namespace should remain with default logging.

.Filter.ByIncludingOnly(Matching.FromSource("SomeNamespace"))

However I would like to reach only method1 inside SomeNamespace and not to reach the method2 also located in the same namespace. Any ideas?

I can't use the serilog levels to achieve this. Most wanted would be the filter usage.


Solution

  • In order to apply a filter the way that you're describing, you'd have to have the method name available as a log context property that you can filter on. There's nothing built-in in Serilog that captures method names, thus you'd have ensure this property gets created when you're writing to the logs.

    Using LogContext you can add a property that you know about, which would flag the log messages to be included (or excluded) by a particular filter.

    e.g.

    using (LogContext.PushProperty("ThisIsSuperCritical", true))
    {
        Log.Information("This message will have the property `ThisIsSuperCritical`...");
        Log.Warning("... and this warning too");
    }
    

    Then in your logging pipeline, you apply a filter on the sub-logger based on the property you're looking for. E.g.

    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Verbose()
        .WriteTo.Logger(wt => wt
            .Enrich.FromLogContext()
            .Filter.ByIncludingOnly(Matching.WithProperty("ThisIsSuperCritical"))
            .WriteTo.SomeSink())
        .CreateLogger();
    

    N.B.: Don't forget to add the Enrich.FromLogContext() otherwise the properties won't be added to the log context.


    For a small number of methods the above is fine. If you have many methods and need to get the name of the method dynamically, then you'd have to use a custom enricher that reflects over the call stack to capture the method name (which might have an impact on performance as it's an expensive operation).