简体   繁体   English

Serilog - 多个日志文件

[英]Serilog - multiple log files

I am using Serilog for logging and cant' figure out how to separate log events to different files.我正在使用 Serilog 进行日志记录,但无法弄清楚如何将日志事件分离到不同的文件中。 For example, I want to log errors to error_log-ddmmyyyy.txt and warnings to warn_log-ddmmyyyy.txt.例如,我想将错误记录到 error_log-ddmmyyyy.txt,将警告记录到 warn_log-ddmmyyyy.txt。

Here goes my logger configuration:这是我的记录器配置:

Log.Logger = new LoggerConfiguration()
            .WriteTo.Logger(lc =>
                lc.Filter.ByIncludingOnly(Matching.WithProperty("Level", "Warning"))
                    .WriteTo.RollingFile(
                        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Logs\warn_log-{Date}.txt"),
                        outputTemplate: OutputTemplate))
            .WriteTo.Logger(lc =>
                lc.Filter.ByIncludingOnly(Matching.WithProperty("Level", "Error"))
                    .WriteTo.RollingFile(
                        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Logs\error_log-{Date}.txt"),
                        outputTemplate: OutputTemplate))
            .CreateLogger();

It only works when I specify {Level} property exatcly in log message.它仅在我在日志消息中明确指定 {Level} 属性时有效。

I was trying to use:我试图使用:

Matching.WithProperty<LogEventLevel>("Level", l => l == LogEventLevel.Warning)

but it didn't work too.但它也没有用。

I use the following configuration and it works for me:我使用以下配置,它对我有用:

            Log.Logger = new LoggerConfiguration()
                    .MinimumLevel.Debug()
                    .WriteTo.LiterateConsole()
                    .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Information).WriteTo.RollingFile(@"Logs\Info-{Date}.log"))
                    .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Debug      ).WriteTo.RollingFile(@"Logs\Debug-{Date}.log"))
                    .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Warning    ).WriteTo.RollingFile(@"Logs\Warning-{Date}.log"))
                    .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error      ).WriteTo.RollingFile(@"Logs\Error-{Date}.log"))
                    .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Fatal      ).WriteTo.RollingFile(@"Logs\Fatal-{Date}.log"))
                    .WriteTo.RollingFile(@"Logs\Verbose-{Date}.log")
                    .CreateLogger();

I think you need:我认为你需要:

.ByIncludingOnly(evt => evt.Level == LogEventLevel.Warning)

Edit:编辑:

In many cases it's now more succinct to use Serilog.Sinks.Map .在许多情况下,现在使用Serilog.Sinks.Map更加简洁。 With it, the example can be written as:有了它,这个例子可以写成:

Log.Logger = new LoggerConfiuration()
    .WriteTo.Map(
        evt => evt.Level,
        (level, wt) => wt.RollingFile("Logs\\" + level + "-{Date}.log"))
    .CreateLogger();

Usually for my use-cases I need multiple logs that will contain a minimum level for each.通常对于我的用例,我需要多个日志,每个日志都包含一个最低级别。 This way I can later investigate the logs more efficiently.这样我以后可以更有效地调查日志。

For more recent versions of Serilog I would suggest to use this:对于更新版本的 Serilog,我建议使用这个:

Log.Logger = new LoggerConfiuration()
    .MinimumLevel.Debug()
    .WriteTo.File(path: "debug.log", rollingInterval: RollingInterval.Day)
    .WriteTo.File(path: "info.log", restrictedToMinimumLevel: LogEventLevel.Information, rollingInterval: RollingInterval.Day)
    .WriteTo.File(path: "error.log",restrictedToMinimumLevel: LogEventLevel.Error, rollingInterval: RollingInterval.Day)
    .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Warning)
    .CreateLogger();

Serilog now has conditional sinks which make it really simple and clean to implement this: Serilog 现在有条件接收器,这使得实现它变得非常简单和干净:

Log.Logger = new LoggerConfiguration()
.WriteTo.Conditional(
    evt => evt.Level == LogEventLevel.Debug,
    wt => wt.RollingFile(@"Logs\Debug-{Date}.log"))
.WriteTo.Conditional(
    evt => evt.Level == LogEventLevel.Warning,
    wt => wt.RollingFile(@"Logs\Warning-{Date}.log"))
.CreateLogger();

You can put whatever condition you like in the first argument.您可以在第一个参数中放入您喜欢的任何条件。

var dateTimeNowString = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}";
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
    .WriteTo.Logger(
        x => x.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Error)
            .WriteTo.File($"Logs/{dateTimeNowString}-Error.log")
    )
    .WriteTo.Logger(
        x => x.Filter.ByIncludingOnly(e => e.Level == LogEventLevel.Warning)
            .WriteTo.File($"Logs/{dateTimeNowString}-Warning.log")
    )
    .WriteTo.File($"Logs/{dateTimeNowString}-All.log")
    .WriteTo.Console()
    .CreateLogger();

These are my nuget packages:这些是我的 nuget 包:

    <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
    <PackageReference Include="Serilog.Sinks.File" Version="4.0.0" />

Another variant is to have ERROR and FATAL in one file (instead of errors in one file and fatal in another).另一种变体是在一个文件中包含 ERROR 和 FATAL(而不是在一个文件中包含错误而在另一个文件中包含致命错误)。 Seems to many files for me having them separate.对我来说,似乎有很多文件将它们分开。 Just to keep in mind "or" operator can be used.请记住,可以使用“或”运算符。

Log.Logger = new LoggerConfiguration()
    .WriteTo.File("logs\\all.log", rollingInterval: RollingInterval.Day)
    .WriteTo.Logger(
        x => x.Filter.ByIncludingOnly(y => y.Level == Serilog.Events.LogEventLevel.Error || y.Level == Serilog.Events.LogEventLevel.Fatal)
        .WriteTo.File("logs\\error.log", rollingInterval: RollingInterval.Day))
    .CreateLogger();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM