Serilog: 将日志记录到不同的文件中。

34

我正在将各种事件记录到单个Json文件中,不考虑日志级别。现在有一个需求,需要将一些自定义性能计数器记录到单独的Json文件中。如何在Serilog中实现这个功能?我应该创建不同的Logger实例,并在记录性能计数器的位置使用它吗?希望能与LibLog一起使用。


可能是Serilog - 多个日志文件的重复问题。 - Michael Freidgeim
4个回答

34
你可以通过首先确保性能计数器事件使用特定属性值(LibLog中的OpenMappedContext())或特定类型/命名空间进行标记来实现此操作。
var log = LogProvider.For<MyApp.Performance.SomeCounter>()
log.Info(...);

配置Serilog时,应用筛选器的子记录器可以将所需的事件仅发送到第二个文件。
Log.Logger = new LoggerConfiguration()
    .WriteTo.Logger(lc => lc
        .Filter.ByExcluding(Matching.FromSource("MyApp.Performance"))
        .WriteTo.File("first.json", new JsonFormatter()))
    .WriteTo.Logger(lc => lc
        .Filter.ByIncludingOnly(Matching.FromSource("MyApp.Performance"))
        .WriteTo.File("second.json", new JsonFormatter()))
    .CreateLogger();

阅读了你的文章:Serilog 2.0 子记录器的冒险。不确定我是否遗漏了什么,但是如果我这样做,来自“MyApp.Performance”的日志也会被写入到外部记录器中,对吧?我不希望这些特定的日志被写入到主日志文件中。 - Shetty
添加两个子日志管道并使用反向过滤器即可。正在更新答案... - Nicholas Blumhardt
那对我有用。编辑答案以删除JsonFormatter。 - Shetty
你有这个的JSON示例吗? - shiva

12

我们也可以在配置文件中进行设置。下面是一个示例,展示如何在appsettings.json中按级别将日志拆分为滚动文件。

{
 
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Default": "Information",
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Information"
      }
    },
    "WriteTo": [
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "(@Level = 'Error' or @Level = 'Fatal' or @Level = 'Warning')"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/ex_.log",
                  "outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
                  "rollingInterval": "Day",
                  "retainedFileCountLimit": 7
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "(@Level = 'Information' or @Level = 'Debug')"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/cp_.log",
                  "outputTemplate": "{Timestamp:o} [{Level:u3}] ({SourceContext}) {Message}{NewLine}{Exception}",
                  "rollingInterval": "Day",
                  "retainedFileCountLimit": 7
                }
              }
            ]
          }
        }
      }
    ],
    "Enrich": [
      "FromLogContext",
      "WithMachineName"
    ],
    "Properties": {
      "Application": "MultipleLogFilesSample"
    }
  }
}

然后,您只需要修改Program.cs文件中的CreateHostBuilder方法,以从配置文件中读取它。

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            })
            .UseSerilog((hostingContext, loggerConfig) =>
                loggerConfig.ReadFrom.Configuration(hostingContext.Configuration)
            );

了解更多详细信息,请参考此处的文章


3
如果您想要一个独立的日志管道,只需创建另一个实例即可。 这是从 https://github.com/serilog/serilog/wiki/Lifecycle-of-Loggers 中借鉴并改编的。
using (var performanceCounters = new LoggerConfiguration()
        .WriteTo.File(@"myapp\log.txt")
        .CreateLogger())
{
    performanceCounters.Information("Performance is really good today ;-)");

    // Your app runs, then disposal of `performanceCounters` flushes any buffers
}

1
我正在使用以下代码将不同级别的日志记录到不同的文件中。
var conn = configuration.GetSection("ConnectionStrings:SqlConn").Value;

var serilogLogger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .WriteTo.Console()
            .WriteTo.MSSqlServer(conn, new MSSqlServerSinkOptions { TableName = "ErrorLogs", AutoCreateSqlTable = true }, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Warning)
            .WriteTo.MSSqlServer(conn, new MSSqlServerSinkOptions { TableName = "InfoLogs", AutoCreateSqlTable = true }, restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Information)
            .CreateLogger();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接