Search code examples
c#loggingserilog

Use Different Serilog Sinks for different purposes in the same class + dependency injection


I need to use Serilog to write some data into elasticsearch, but I want to write all other logs to a different sink, like Console. Is this possible? How should I modify the main and CreateHostBuilder methods to achieve that?

What I want is something like this:

 public class Processor
   {
      private readonly ILogger<Processor> _logger;

      public Processor(ILogger<Processor> logger)
      {
         _logger = logger;
      }

      public void Process(object message1, string message2, string message 3)
      {
          _logger.LogInformation("processor started);
          _logger.LogInfomration("{@message1}", message1);//want this use a console sink
          _logger.LogInfomration("{@message2}", message2);//want this use a eleasticsearch sink
          _logger.LogInfomration("{@message3}", message3);//want this use a console sink
      }

my current main and CreateHostBuilder methods are:

  public static async Task Main(string[] args)
  {
     Log.Logger = new LoggerConfiguration()
        .WriteTo.Elasticsearch(
           options: new ElasticsearchSinkOptions(new 
           Uri("http://localhost:9200"))
           {
              AutoRegisterTemplate = true,
           

   IndexFormat = $" 
       {Assembly.GetExecutingAssembly().GetName().Name.ToLower().Replace(".", 
        "-")}-" + $"{DateTime.UtcNow:MM-dd-yyyy}",
               })
            .CreateLogger();

         await CreateHostBuilder(args)
            .Build()
            .RunAsync()
            .ConfigureAwait(false);

         Log.CloseAndFlush();
      }



 public static IHostBuilder CreateHostBuilder(string[] args, StringBuilder configLog) =>
         CreateDefaultBuilder(args)
            .UseSerilog();
            

Solution

  • You can use .WriteTo.Conditional, for example to differentiate based on template text:

    logOpts.WriteTo.Conditional(le => le.MessageTemplate.Text.Contains("message2"),
       cfg => cfg.Elasticsearch(....));
    

    Or look into using Serilog.Filters.Expressions with sub-loggers.