c# - 使用 appsettings.json 配置 Serilog 以将某些日志过滤到不同的文件

标签 c# .net-core serilog

我有一个使用 Serilog 将日志数据写入文件的应用程序。我现在正尝试以这种方式在 appsettings.json 中使用子记录器配置我的记录器,以便我可以将某些日志过滤到不同的文件中。我知道我可以在代码中配置记录器,但我想通过 appsettings.json 来完成。

基本上,除了特定类型的日志,我希望所有日志都转到同一个文件。我用了Serilog wiki以及一些博客文章和 stackoverflow 条目,主要是 this one ,以实现我的目标。根据我阅读的内容,使用以下内容应该允许我过滤此类日志条目:

using (LogContext.PushProperty("SpecialLogType", true)) {
    _logger.LogInformation("MyLogEntry {MyParam}", myParam);
}

我配置了两个接收器,一个用于普通日志,一个用于这种特殊类型的日志。使用过滤器,我现在应该能够使用此属性过滤日志。但我无法弄清楚我需要如何在 appsettings.json 中配置子记录器。 现在,我的 appsettings.json 看起来像这样:

"Serilog": {
    "Using": [ "Serilog.Sinks.File", "Serilog.Settings.Configuration", "Serilog.Expressions" ],
    "MinimumLevel": {
      "Default": "Information",
    },
    "WriteTo": [
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByExcluding",
                "Args": {
                  "expression": "@p['SpecialLogType'] = 'true'"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/NormalTypeLog_.txt",
                  // other configuration
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "@p['SpecialLogType'] = 'true'"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/SpecialTypeLog.json",
                  // other configuration
                }
              }
            ]
          }
        }
      }
    ]
  }

我已经尝试了几种不同的方法并取得了一些结果,但我无法让它正常工作并且会接受一些建议。有人有小费吗?

最佳答案

所以几天后我设法解决了这个问题,并想如果有人遇到类似问题,我会在这里发布我的完整解决方案。

我认为我走在正确的道路上,但我的主要问题是我对 Serilog's expressions 的错误使用包裹。我将在多个示例中发现的东西混合在一起,但最终没有奏效。更多阅读 wiki 和 nblumhardt's blog posts引导我找到最终的解决方案。

通过Serilog的appsettings.json配置过滤日志事件到不同的文件

可以使用属性丰富日志。稍后可以在管道中使用这些属性将日志过滤到不同的 subloggers .可以通过 LogContext 类将属性添加到日志。

using (LogContext.PushProperty("SpecialLogType", true)) {
    _logger.LogInformation("This is a log entry that will be filtered to a different file");
}

要实际配置记录器,您需要创建两个子记录器。 过滤必须发生在子记录器级别。每个子记录器都必须过滤它自己的事件。在顶级记录器中过滤将过滤掉所有它的子记录器的日志事件。通过 Serilog's expressions 完成过滤包。

为了仅包含附加我的属性的日志事件,我执行了以下操作

"Name": "ByIncludingOnly",
"Args": {
  "expression": "SpecialLogTypeis not null"
}

因为我希望所有其他事件都转到“标准”文件,所以对于我的其他子记录器,我只是排除了所有附加属性的日志事件

"Name": "ByExcluding",
"Args": {
  "expression": "SpecialLogTypeis not null"
}

完整相关的 appsettings.json 部分

  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File", "Serilog.Settings.Configuration", "Serilog.Expressions" ],
    "WriteTo": [
      { "Name": "Console" },
      { "Name": "Debug" },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByExcluding",
                "Args": {
                  "expression": "SpecialLogType is not null"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/NormalLogEvents_.txt",
                  // other irrelevant file configuration
                }
              }
            ]
          }
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "Filter": [
              {
                "Name": "ByIncludingOnly",
                "Args": {
                  "expression": "SpecialLogType is not null"
                }
              }
            ],
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "Logs/SpecialLoggingType_.log",
                  // other irrelevant file configuration
                }
              }
            ]
          }
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
  }

这对我有用,我希望它能帮助遇到同样问题的任何人。

也很有用:Serilog settings configuration readme

关于c# - 使用 appsettings.json 配置 Serilog 以将某些日志过滤到不同的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73077635/

相关文章:

c# - P/Invoke - 结构参数的简单添加

c# - Columns.Bound 无法解析符号 'Bound'

c# - 如何将此 MySQL 查询编写为 T-SQL?

c# - 已添加具有相同键的项目

c# - 在 .Net Core 中将 HTTP/JSON 转码为 gRPC

entity-framework - 升级到 .NET Core 1.0 项目文件后无法在 EF6 上运行 'dotnet ef'

.net - 如何在通用 Windows 平台应用程序中更新一个特定的 dotnet 程序集?

c# - 使用 C# UWP 的 Serilog WriteTo.File

c# - 使用 serilog 在多个项目中使用相同的日志文件

windows-services - 指定 Serilog 滚动文件路径的目录