首页 > 解决方案 > 使用参数化工厂方法配置和 Serilog 接收器

问题描述

该软件包Serilog.Settings.Configuration支持将 Microsoft ILogger 配置设置与 Serilog 一起使用。

    "Console": {
      "LogLevel": {
        "Default": "Debug"
      }
    },

映射到这个(如果我理解正确的话)

.MinimumLevel.Override("Console", LogEventLevel.Debug)
.WriteTo.Console()

我编写了一个用于 MQTT 的自定义接收器。构造接收器的扩展方法需要参数。一个不能真正表达为字符串。

.WriteTo.MqttSink(managedMqttClientObject, "name of application emitting logs")

我想Serilog.Settings.Configuration与我的自定义水槽一起使用,但可以就如何最好地解决这个问题提出建议。

到目前为止的想法

我也可以这样做

var loggerFactory = new LoggerConfiguration()
.ReadFrom.Configuration(config)
.WriteTo.MqttSink(managedMqttClient, "log source name");

但我不确定当Serilog.Settings.Configuration找不到无参数工厂方法时会发生什么MqttSink。如果有比静态属性方法更好的方法,我将非常感谢您的指导。

标签: c#.net-coreserilogmqttnet

解决方案


这不是配置的工作方式。您需要一个 Serilog 部分。存储库的自述文件中有一个示例。

显然你的配置文件不能提供managedMqttClient,但是如果你添加一种方法来为定义工厂方法的类设置默认值,你可以使参数对于工厂方法是可选的。在工厂方法中,您可以回退到默认值,就像这样。

    public static void SetDefaults(
      IManagedMqttClient managedMqttClient, 
      string eventSource = null)
    {
      __eventSource = eventSource;
      __managedMqttClient = managedMqttClient;
    }

...

    public static LoggerConfiguration MqttSink(
              this LoggerSinkConfiguration loggerConfiguration,
              IManagedMqttClient managedMqttClient = null,
              string eventSource = null,
              IFormatProvider formatProvider = null)
    {
      var sink = new MqttSink(
        formatProvider, managedMqttClient ?? __managedMqttClient, 
        eventSource ?? __eventSource);
      var config = loggerConfiguration.Sink(sink);
      return config;
    }

这种安排甚至允许您使用配置文件覆盖“默认”事件源字符串,因为在 Serilog 配置中提供它会导致将参数值提供给工厂方法。

  "Serilog": {
    "Using": [
      "Serilog.Sinks.Mqtt"
    ],
    "MinimumLevel": "Information",
    "WriteTo": [
      {
        "Name": "MqttSink",
        "Args": {
          "eventSource": "test-client"
        }
      }
    ]
  }

假设上述配置,您的客户端代码可能如下所示。我可以从默认值中省略事件源,因为它是在配置中定义的。

MqttSink.SetDefaults(managedMqttClient);
var loggerFactory = new LoggerConfiguration().ReadFrom.Configuration(config);

这些更改保留了原始调用签名,因此它们不会破坏任何现有代码。


推荐阅读