.NET Core 3.1:如何将已配置的Serilog日志实例从MqttCommunicationClient传递至MQTT处理器
解决方法:将已配置的Serilog实例传递给MQTT API的Handler
首先,问题的核心是你在Initialize方法中创建的新Host(serviceHost)没有正确集成Serilog,导致它默认使用了控制台日志提供者,而非你已经配置好的Serilog实例。以下是具体的修正步骤:
步骤1:在新Host中集成已有的Serilog实例
修改Initialize方法里的Host创建逻辑,用.UseSerilog()直接关联你已注入的Serilog实例,替代手动添加services.AddSingleton(logger)的方式:
public void Initialize() { var mqttClientId = $"{DefaultClientIdPattern}{Environment.MachineName}"; // 从注入的ILogger中提取Serilog核心实例 var serilogLogger = (logger as Serilog.Extensions.Logging.SerilogLogger)?.Logger ?? throw new InvalidOperationException("当前Logger不是Serilog实例"); serviceHost = Host.CreateDefaultBuilder() // 直接关联已配置好的Serilog实例 .UseSerilog(_ => serilogLogger) .UseMQTTApi(opt => { opt.UserName = "test"; opt.Password = "test"; }) .Start(); managedMqttClient = serviceHost.Services.GetRequiredService<IManagedMqttClient>(); }
步骤2:理解为什么原方式不生效
你之前手动注册的services.AddSingleton(logger)是非泛型的ILogger,但ConnectionStatusHandler依赖的是泛型的ILogger
通过.UseSerilog()集成后,Serilog会自动为所有ILogger<T>类型提供实例,确保整个Host内的日志都使用你配置好的Serilog。
补充:优化你的Serilog配置代码(可选但推荐)
你的CreateLogger方法存在一个潜在问题:在using块中创建SerilogLoggerProvider会导致提供者被提前释放,可能引发后续日志异常。建议调整为在DI容器中注册Serilog提供者:
public IServiceProvider CreateServiceProvider(string basePath) { var configuration = GetConfiguration(basePath); // 创建Serilog核心实例 var serilogLogger = new LoggerConfiguration() .ReadFrom.Configuration(configuration) .CreateLogger(); var services = new ServiceCollection(); // 注册Serilog日志提供者(单例) services.AddSingleton<ILoggerProvider>(new SerilogLoggerProvider(serilogLogger)); // 注册通用ILogger实例 services.AddSingleton<ILogger>(sp => sp.GetRequiredService<ILoggerProvider>().CreateLogger("Default")); return services.BuildServiceProvider(); }
按照以上步骤修改后,ConnectionStatusHandler中注入的ILogger<ConnectionStatus>就会使用你配置好的Serilog实例,日志就能正常写入文件了。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

