2

I'm using serilog to log all the Web API trace events in to one file and all the code debug to another file by the below code:

The problem is that the trace.json is also logging Debug events as well which I suspect is because of the minimumLevel filter.

How do I separate the events into two files ?

Tried this Question, but it doesn't write the file at all.

Using latest serilog version.

Log.Logger = new LoggerConfiguration()
.WriteTo.Trace(outputTemplate: "{Timestamp} [{Level}] ({HttpRequestId}|{UserName}) {Message}{NewLine}{Exception}")
.MinimumLevel.Debug()
.WriteTo.Sink(new FileSink(@"E:\log.json", new JsonFormatter(false, null, true), null), LogEventLevel.Debug)
.MinimumLevel.Verbose()
.WriteTo.Sink(new FileSink(@"E:\trace.json", new JsonFormatter(false, null, true), null), LogEventLevel.Verbose)
.Enrich.With<HttpRequestIdEnricher>()
.Enrich.With<UserNameEnricher>()
.Enrich.WithProperty("App", "CarbonFactoryERP")
.CreateLogger();

and below is how I call the logger:

Log.Logger.Debug("Web API Register Method started at {TimeStamp}",DateTime.UtcNow);

Log.Logger.Verbose("{TimeStamp} {Operation} {Operator} {Message} {Category}", rec.Timestamp, rec.Operation, rec.Operator, rec.Message, rec.Category);
Dev
  • 987
  • 2
  • 14
  • 32

2 Answers2

1

This is the expected behavior of Serilog sinks. The minimum level parameter specifies only the minimum, as you'd expect - not an exact level match.

To get around this and write only a specific level to a sink, you can create a separate logging pipeline with the restriction applied and use that:

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Verbose()
    .WriteTo.Logger(config => config
        .Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Debug)
        .WriteTo.Sink(new FileSink(@"E:\trace.json", ...))
    // Write to other sinks here

(May need a few typo corrections, working from memory.)

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101
  • As already mentioned in the question, I tried this and the log file is not getting written at all when I use the Filter. I tried again and still same. – Dev Mar 24 '15 at 03:49
  • I've decided to go with multiple top level loggers until I get this working. – Dev Mar 24 '15 at 13:50
0

This example will log to the same sink (but could write to different ones) depending in the log level and SourceContext (Application namespace, class name etc.). It has a verbose minimun log level for all classes of MyAppRootNamespace and a warning minimun log level for other source contexts (Microsoft.* etc.). This will give you a starting point to your exact needs.

Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Verbose()
                .Enrich.FromLogContext()
                .WriteTo.Logger(lc => lc
                    .Filter.ByIncludingOnly(Matching.FromSource("MyAppRootNamespace"))
                    .WriteTo.Seq("http://localhost:1009"))
                .WriteTo.Logger(lc => lc
                    .Filter.ByIncludingOnly(e => e.Level >= LogEventLevel.Warning)
                    .Filter.ByExcluding(Matching.FromSource("MyAppRootNamespace"))
                    .WriteTo.Seq("http://localhost:1009"))
                .CreateLogger();

For the source context (MyAppRootNamespace) to work you will need to add a vble to each class you want to log from.

public class MyClass
{
    private ILogger _log = Log.ForContext<MyClass>();
}
mattinsalto
  • 2,146
  • 1
  • 25
  • 27