11

I'm going to implement Serilog within .net standard 2.0 library. I'm looking for a way to choose which sink(s) should be used for each log line.

Lets say that we define 2 sinks within the configuration (console & file) :

    Log.Logger = new LoggerConfiguration()
        .MinimumLevel.Debug()
        .WriteTo.Console()
        .WriteTo.File("c:\\temp\\SerilogTets.txt")
        .CreateLogger();

After this, we are going to write one log rule :

Log.Information("Hello, world!");  //<- how can we define which sink we want to use

I'm looking for a way howto define for which sink(s) those lines should be logged for :

  • Console & File
  • Console only
  • File only

Without relying on what loglevel it is.

Thank you in advance!

Kind regards, Kurt

Kurt Colemonts
  • 133
  • 1
  • 7
  • 4
    You do that by specifying filter conditions in the configuration. The application code shouldn't know anything about the sinks. That defeats the purpose of using a logging library to begin with - decouple application code from logging sinks. – Panagiotis Kanavos Jan 08 '21 at 11:44
  • Besides, one can't tell you how to select a sink if you don't explain what the criteria are for selecting one sink or another. – Panagiotis Kanavos Jan 08 '21 at 11:45
  • What @PanagiotisKanavos says, see https://stackoverflow.com/questions/46516359/filter-serilog-logs-to-different-sinks-depending-on-context-source – CodeCaster Jan 08 '21 at 11:45
  • 1
    Thanks for your quick response. The main reason is : There is data that we do want to log only to log files because of security reasons. Other log information may be logged to application insights. It's more to want to have a choice what we want to push to application insights and what not. – Kurt Colemonts Jan 08 '21 at 11:48
  • 2
    That's what filtering in the logger configuration does. You can specify filters by category and extra context properties – Panagiotis Kanavos Jan 08 '21 at 12:22

1 Answers1

14

In Serilog you can do this separation via sub-loggers using filters or via Serilog.Sinks.Map, using context properties to decide which logger will include or exclude certain messages.

The example below defines that all log events will be written to both the Console and to a File, by default, however if the log event has a property called FileOnly in the log context, it will not be written to the Console, and likewise if the log event has a property called ConsoleOnly, it will not be written to the File.

using Serilog;
using Serilog.Context;
using Serilog.Filters;
// ...

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .Enrich.FromLogContext()
    .WriteTo.Logger(c =>
        c.Filter.ByExcluding(Matching.WithProperty("FileOnly"))
            .WriteTo.Console())
    .WriteTo.Logger(c =>
        c.Filter.ByExcluding(Matching.WithProperty("ConsoleOnly"))
            .WriteTo.File("C:\\Temp\\SerilogTests.txt"))
    .CreateLogger();

// Writes to both Console & File
Log.Information("Hello, world! (Console and File)");

using (LogContext.PushProperty("ConsoleOnly", value: true))
{
    // Writes only to the Console
    Log.Information("Hello, world! (Console)");
}

using (LogContext.PushProperty("FileOnly", value: true))
{
    // Writes only to the File
    Log.Information("Hello, world! (File Only)");
}

Log.CloseAndFlush();

N.B.: Ideally you'll come up with better property names that are more generic, so that when you are writing logs within your application it doesn't have to know anything about "Console" or "File". e.g. You could have a property called Secret or Classified and decide where to write the logs based on the presence of this property or not.

There are different ways to add properties to a log event, including adding the property in the message template directly when you Log.Information, etc., via LogContext.PushProperty as in the example above, and vi Log.ForContext.

You can see other examples of filtering, sub-loggers, and Serilog.Sinks.Map here:

C. Augusto Proiete
  • 24,684
  • 2
  • 63
  • 91
  • Thanks for providing your answer. I did found this one before, but the problem i have with that one is that it will also log the (console) & (File only) within the log file. – Kurt Colemonts Feb 03 '21 at 08:00
  • @KurtColemonts I'm not sure I understand what you mean. Do you want to update your question with more details? – C. Augusto Proiete Feb 03 '21 at 18:36