skip to Main Content

This is how my logging in Asp.Net is configured:

    _ = pServiceCollection.AddSerilog((serviceProvider, loggerConfiguration)
                                          => loggerConfiguration.ReadFrom.Configuration(pConfiguration)
                                                                .ReadFrom.Services(serviceProvider)
                                                                .Enrich.FromLogContext()
                                                                .WriteTo.Console(outputTemplate: LogMessageTemplate,
                                                                                 formatProvider: CultureInfo.InvariantCulture)
                                                                .WriteTo.File(path: logFilePath,
                                                                              outputTemplate: LogMessageTemplate,
                                                                              rollingInterval: RollingInterval.Day,
                                                                              retainedFileCountLimit: 30,
                                                                              formatProvider: CultureInfo.InvariantCulture)
                                                                .WriteTo.EventLog(source: CommonConstants.ProductName,
                                                                                  manageEventSource: true,
                                                                                  restrictedToMinimumLevel: LogEventLevel.Warning,
                                                                                  formatProvider: CultureInfo.InvariantCulture));

Only Warning or higher will be logged to the event log (because of restrictedToMinimumLevel)

But there is one type of Info level logging that I want to log to the event log, too.

I tried out appending this limitation (Filter.ByIncludingOnly) and using a "category", but unfortunately, this will be applied to all sinks. I want it only for the event log sink.

.WriteTo.File(path: logFilePath,
              outputTemplate: LogMessageTemplate,
              rollingInterval: RollingInterval.Day,
              retainedFileCountLimit: 30,
              formatProvider: CultureInfo.InvariantCulture)
.WriteTo.EventLog(source: CommonConstants.ProductName,
                  manageEventSource: true,
                  restrictedToMinimumLevel: LogEventLevel.Warning,
                  formatProvider: CultureInfo.InvariantCulture)
.Filter.ByIncludingOnly(e =>
                            (e.Level == LogEventLevel.Information &&
                             (e.Properties.ContainsKey("SourceContext") &&
                              e.Properties["SourceContext"].ToString().Contains(CommonConstants.ForceLoggingToEventLogCategory))) ||
                            e.Level >= LogEventLevel.Warning));

This was the other side:

var forcelogger = app.Services.GetService<ILoggerProvider>()!.CreateLogger(CommonConstants.ForceLoggingToEventLogCategory);
forcelogger.LogInformation("force hallo Welt");


Conclusion: I like the logging setup with Asp.Net logging and Serilog and want only warning and higher in the event log, but there are 2-3 exceptions. Is it possible to achieve this?

2

Answers


  1. You should add a custom sink filter like this:

    _ = pServiceCollection.AddSerilog((serviceProvider, loggerConfiguration) =>
    {
        // Create a custom filter for the Event Log
        bool EventLogFilter(LogEvent e) =>
            e.Level >= LogEventLevel.Warning || 
            (e.Level == LogEventLevel.Information && 
             e.Properties.ContainsKey("SourceContext") && 
             e.Properties["SourceContext"].ToString().Contains(CommonConstants.ForceLoggingToEventLogCategory));
    
        loggerConfiguration
            .ReadFrom.Configuration(pConfiguration)
            .ReadFrom.Services(serviceProvider)
            .Enrich.FromLogContext()
            .WriteTo.Console(
                outputTemplate: LogMessageTemplate,
                formatProvider: CultureInfo.InvariantCulture)
            .WriteTo.File(
                path: logFilePath,
                outputTemplate: LogMessageTemplate,
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 30,
                formatProvider: CultureInfo.InvariantCulture)
            .WriteTo.EventLog(
                source: CommonConstants.ProductName,
                manageEventSource: true,
                restrictedToMinimumLevel: LogEventLevel.Information,  // Lower this to Information
                filter: EventLogFilter,  // Add the custom filter here
                formatProvider: CultureInfo.InvariantCulture);
    });
    
    Login or Signup to reply.
  2. You can create another sink with its own filter.

    I always get tripped up by the syntax required to filter specific loggers too. The way the Fluent API works, you need to create a sub-logger to specify filters for individual loggers. Otherwise the filter apply to all sinks. That’s the only way you can keep chaining calls.

    The alternative would be to break the chain of calls and configure sinks in separate statements.

    In this example, Information events generated by the AdminController source will be logged to the Event log.

    .WriteTo.EventLog(source: CommonConstants.ProductName,
                      manageEventSource: true,
                      restrictedToMinimumLevel: LogEventLevel.Warning,
                      formatProvider: CultureInfo.InvariantCulture))
    .WriteTo.Logger(lc => lc
            .Filter.ByIncludingOnly(Matching.FromSource<AdminController>())
            .WriteTo.EventLog(source: CommonConstants.ProductName,
                      manageEventSource: false,
                      restrictedToMinimumLevel: LogEventLevel.Information,
                      formatProvider: CultureInfo.InvariantCulture))
    );
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search