3

我们正在编写一个新的日志功能并注入到我们现有的服务中。

以下是我们的做法:

1) 在 Program.cs 中使用 UseSerilog() 调用设置 Serilog

2) 在 appsettings.json 中设置 Serilog 配置以设置接收器以写入日志文件。

3) 编写了一个 Facade Custom Logger 类,它使用 Serilog 全局 Log 实例在内部进行日志记录。

public class MyLogger<T> : IMyLogger<T>
public MyLogger()
    {
        _logger = Log.ForContext(typeof(T));
    }
public void LogInformation(Exception ex)
    {
        _logger.Information(ex.Message);
    }

4) 通过 DI 将 IMyLogger 注入到我现有的所有服务中

5)在ConfigureServices()中注册所有服务(Logger、Project相关服务)

一切正常。但是我想在我的应用程序中为不同的命名空间设置不同的日志级别,以便在生产中我可以简单地在配置中设置只有 4-5 个重要的核心命名空间,其日志记录方法调用 (MyLogger.LogInformation()) 将被发送到日志文件。

像下面这样的可能吗?因为 MyLogger 是记录的类。但是如果调用来自 MyProject.CartManager 命名空间,那么它应该根据示例中的以下配置自动记录。

请分享你的想法。

例如:

"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft": "Warning",
    "System": "Information",
    "MyProject.Inventory":  "Information"
    "MyProject.CartManager":  "Error"
  }
}
4

2 回答 2

1

正如您在配置中所建议的那样。可以这样做。下面是示例配置。

"serilog": {
"Using": [ "Serilog.Sinks.Console" ],
"MinimumLevel": {
  "Default": "Information",
  "Override": {
    "Microsoft": "Warning",
    "Microsoft.Hosting.Lifetime": "Information"
  }
},
"WriteTo": [
  {
    "Name": "Console",
    "Args": {
      "formatter": "Serilog.Formatting.Elasticsearch.ElasticsearchJsonFormatter,Serilog.Formatting.Elasticsearch"
    }
  }
]}

MinimumLevel 配置部分规定了默认值和特定命名空间的覆盖。

  1. 默认日志级别是信息。
  2. Microsoft 命名空间中除 Microsoft.Hosting.Lifetime 之外的类的最低日志级别应为警告

作为旁注,我将我的 Serilog 注册为

webBuilder.UseSerilog((ctx, lc) => lc.ReadFrom.Configuration(ctx.Configuration));

格式化程序部分在问题的上下文中是微不足道的,但如果你想使用它,我将Serilog.Sinks.ElasticSearch作为额外的包来使用它。

于 2022-01-18T13:38:33.310 回答
0

你的IMyLogger好像过分了。微软Microsoft.Extensions.Logging出于同样的目的提供。所以你可以只注入ILogger<MyProject.Inventory.Foo>到你的类中,Serilog 用Serilog.Extensions.Logging包处理它。除此之外,您的示例必须按原样工作,满足您的期望。可能对于您的特定注射,您使用了错误T(实施没有检查)。

刚开始在谷歌上搜索几乎相同的内容:MinimumLevel对一些专用的命名空间或上下文使用覆盖,首先发现这个问题没有答案,但接下来是这篇很棒的文章

要点:

的第一个参数Override是源上下文前缀,通常与与记录器关联的类的命名空间限定类型名称匹配。

// Using Serilog:
var myLog = Log.ForContext<MyClass>();
myLog.Information("Hello!");
// -> SourceContext is "MyNamespace.MyClass"
//Using Microsoft.Extensions.Logging:
var myLog = loggerFactory.CreateLogger("MyNamespace.MyClass");
myLog.LogInformation("Hello!");
// -> SourceContext is "MyNamespace.MyClass"
于 2020-06-24T16:31:10.237 回答