根据上下文源将 Serilog 日志过滤到不同的接收器? [英] Filter Serilog logs to different sinks depending on context source?

查看:26
本文介绍了根据上下文源将 Serilog 日志过滤到不同的接收器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .NET Core 2.0 应用程序,我在其中成功使用 Serilog 进行日志记录.现在,我想将一些数据库性能统计信息记录到一个单独的接收器(它们不是用于调试,这基本上是应用程序中所有其他日志记录的目的,所以我想将它们分开)并认为这可以完成通过使用 Log.ForContext() 创建数据库统计记录器.

I have a .NET Core 2.0 application in which I successfully use Serilog for logging. Now, I would like to log some database performance statistics to a separate sink (they are not for debugging, which basically is the purpose of all other logging in the application, so I would like to keep them separate) and figured this could be accomplished by creating the DB statistics logger with Log.ForContext<MyClass>().

我不知道我应该如何配置 Serilog 使用我的 appsettings.json 将我的调试日志"记录到一个接收器并将我的数据库统计记录记录到另一个接收器?我希望有可能做这样的事情:

I do not know how I am supposed to configure Serilog using my appsettings.json to log my "debug logs" to one sink and my DB statistics log to another? I am hoping it is possible to do something like:

"Serilog": {
  "WriteTo": [
    {
      "Name": "RollingFile",
      "pathFormat": "logs/Log-{Date}.log",
      "Filter": {
        "ByExcluding": "FromSource(MyClass)"
      }
    },
    {
      "Name": "RollingFile",
      "pathFormat": "logs/DBStat-{Date}.log",
      "Filter": {
          "ByIncludingOnly": "FromSource(MyClass)"
      }
    }
  ]
}

配置的 过滤器" 部分纯属我的猜测.这可以使用我的配置文件管理器还是我需要在我的 Startup.cs 文件中的代码中执行此操作?

The "Filter" parts of the configuration is pure guesswork on my part. Is this possible using my configuration filer or do I need to do this in code in my Startup.cs file?

我已经使用 C# API 让它工作了,但仍然想使用 JSON 配置来解决它:

I have got it working using the C# API but would still like to figure it out using JSON config:

Log.Logger = new LoggerConfiguration()
            .WriteTo.Logger(lc => lc
                .Filter.ByExcluding(Matching.FromSource<MyClass>())
                .WriteTo.LiterateConsole())
            .WriteTo.Logger(lc => lc
                .Filter.ByExcluding(Matching.FromSource<MyClass>())
                .WriteTo.RollingFile("logs/DebugLog-{Date}.log"))
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(Matching.FromSource<MyClass>())
                .WriteTo.RollingFile("logs/DBStats-{Date}.log", outputTemplate: "{Message}{NewLine}"))
            .CreateLogger();

推荐答案

我今天完成了这项工作,并认为我会提供一个正确的答案,因为我花了很多帖子、问题和其他页面来完成解决这个问题.

I completed this work today, and thought that I'd provide a proper answer since it took me quite a few posts, issues and other pages to work through to get this sorted out.

拥有所有日志很有用,但我也想单独记录我的 API 代码,并省略 Microsoft. 命名空间日志.执行此操作的 JSON 配置如下所示:

It's useful to have all the logs, but I also wanted to log only my API code separately, and omit the Microsoft. namespace logs. The JSON config to do that looks like this:

  "Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": "Debug",
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "/var/logs/system.log",
          ... //other unrelated file config
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {
            "WriteTo": [
              {
                "Name": "File",
                "Args": {
                  "path": "/var/logs/api.log",
                  ... //other unrelated file config
                }
              }
            ],
            "Filter": [
              {
                "Name": "ByExcluding",
                "Args": {
                  "expression": "StartsWith(SourceContext, 'Microsoft.')"
                }
              }
            ]
          }
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ]
    ... //Destructure and other config
  }

顶级WriteTo 是第一个简单的全局接收器.所有日志事件都写入此.如果在与此相同的级别添加 Filter 部分,它将影响所有配置的 WriteTo 元素.

The top-level WriteTo is the first simple, global, sink. All log events write to this. If you add a Filter section on the same level as this, it will affect all configured WriteTo elements.

然后我将另一个 WriteTo 配置为 Logger(不是 File),但是 Args 看起来像有一个configureLogger元素,与Serilog在顶层有相同的作用,也就是说,它是子记录器的顶层.这意味着您可以轻松地将其配置拆分为一个单独的文件,并将其添加到配置构建器中(见底部).

Then I configure another WriteTo as a Logger (not File), but the Args for this looks different and has a configureLogger element which serves the same purpose as Serilog on the top level, that is to say, it is the top level of the sub-logger. This means that you can easily split out the config for this into a separate file and add it additionally in the config builder (see bottom).

从这里开始,这个子记录器的工作方式是一样的:你可以配置多个WriteTos,这个级别的Filter元素只会影响这个子记录器.

From here, this sub-logger works the same way: You can configure multiple WriteTos, and the Filter element on this level will affect only this sub-logger.

只需将更多 "Name": "Logger" 元素添加到顶级 WriteTo 部分,并分别为每个元素设置过滤器.

Simply add more "Name": "Logger" elements to the top level WriteTo section and setup filters for each one separately.

注意同样重要的是要注意,即使您在 config 中执行所有这些操作并且没有在代码中引用 Serilog.Filters.Expressions 包的一个位,您仍然必须添加 NuGet 引用到那个包裹.没有包引用就无法工作.

Note It is also important to note that, even though you are doing all this in config and not referencing a single bit of the Serilog.Filters.Expressions package in your code, you still have to add the NuGet reference to that package. It doesn't work without the package reference.

关于拆分配置:

如果我必须添加更多记录器,为了清楚起见,我肯定会将不同的记录器拆分为单独的文件,例如

If I have to add more loggers, I would definitely split out the different loggers into separate files for clarity, e.g.

appsettings.json:

appsettings.json:

  "Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "MinimumLevel": "Error",
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "/var/logs/system.log",
          ...
        }
      },
      {
        "Name": "Logger",
        "Args": {
          "configureLogger": {} // leave this empty
        }
      }
    ],
    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
    ...

apilogger.json:

apilogger.json:

{
  "Serilog:WriteTo:1:Args:configureLogger": {   //notice this key
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "/var/logs/api_separateFile.log",
          ...
        }
      }
    ],
    "Filter": [
      {
        "Name": "ByExcluding",
        "Args": {
          "expression": "StartsWith(SourceContext, 'Microsoft.')"
        }
      }
    ]
  }
}

然后调整我的 IWebHost 构建器以包含额外的配置:

And then adjust my IWebHost builder to include the additional config:

    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile("apilogger.json", optional: false, reloadOnChange: false);
        })
        .UseStartup<Startup>();

这样更容易理解、阅读和维护.

This way it is easier to understand, read and maintain.

这篇关于根据上下文源将 Serilog 日志过滤到不同的接收器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆