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

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

问题描述

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

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>().

我不知道如何使用我的appsettings.json 配置Serilog,以便将调试日志"记录到一个接收器中,而将数据库统计信息记录到另一个接收器中?我希望可以做类似的事情:

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)"
      }
    }
  ]
}

该配置的"Filter"部分只是我的猜测.可以使用我的配置文件管理器来完成此操作吗?还是需要在我的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).

从此处开始,此子记录器的工作方式相同:您可以配置多个WriteTo,并且此级别上的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.

只需在顶级WriteTo部分中添加更多"Name": "Logger"元素,然后分别为每个元素设置过滤器即可.

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天全站免登陆