You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.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。DI容器无法自动将非泛型实例映射到泛型版本,而新Host默认会使用控制台日志提供者,所以才会出现日志只输出到控制台的情况。

通过.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:12:47