基于ILogger封装日志类跨多类使用的问题排查
解决C# SDK日志组件的两个问题:Application Insights日志丢失与Trace级别不显示
问题1:Application Insights仅接收基类日志
原因
- InMemoryChannel被提前释放:你在
LoggerBase构造函数里用using var channel = new InMemoryChannel();,构造函数执行完毕后通道会被自动释放,导致后续TestClass中LoggerBase实例生成的日志无法通过该通道发送到Application Insights。 - 重复创建服务容器:每次实例化
LoggerBase<T>都会新建ServiceCollection和ServiceProvider,不仅低效,还会导致每个LoggerBase实例对应的日志通道独立且短命,无法完成遥测数据的发送。
解决办法
将日志服务的初始化逻辑改为全局单例,确保通道和服务容器的生命周期与应用一致,同时移除InMemoryChannel的using声明:
// 全局日志服务初始化类 public static class LoggerFactory { private static IServiceProvider _serviceProvider; static LoggerFactory() { var channel = new InMemoryChannel(); IServiceCollection services = new ServiceCollection(); services.Configure<TelemetryConfiguration>(config => config.TelemetryChannel = channel); services.AddLogging(builder => { builder.AddApplicationInsights( configureTelemetryConfiguration: config => config.ConnectionString = "<YourConnectionString>", configureApplicationInsightsLoggerOptions: options => { } ); }); _serviceProvider = services.BuildServiceProvider(); } public static ILogger<T> GetLogger<T>() { return _serviceProvider.GetRequiredService<ILogger<T>>(); } } // 简化后的LoggerBase public class LoggerBase<T> { private readonly ILogger<T> _logger; public LoggerBase() { _logger = LoggerFactory.GetLogger<T>(); _logger.LogInformation("Test Log from Base Class"); } public ILogger<T> GetInstance() => _logger; }
此时TestClass的日志能正常发送到Application Insights,因为所有日志实例共享同一个持久化的通道和服务容器。
问题2:控制台无法显示LogTrace级别日志
原因
.NET默认的控制台日志提供程序最低输出级别为LogLevel.Information,Trace级别的日志会被自动过滤。
解决办法
在日志配置中明确设置控制台日志的最低级别,修改上面LoggerFactory中的AddLogging部分:
services.AddLogging(builder => { builder.AddApplicationInsights( configureTelemetryConfiguration: config => config.ConnectionString = "<YourConnectionString>", configureApplicationInsightsLoggerOptions: options => { } ); // 配置控制台日志输出Trace级别 builder.AddConsole(options => { options.LogToStandardErrorThreshold = LogLevel.Trace; }).SetMinimumLevel(LogLevel.Trace); });
配置完成后,LogTrace级别的日志就能正常输出到控制台了。
额外建议
如果是SDK开发,建议让使用者通过依赖注入方式提供ILogger<T>,而非自行封装日志组件,这样更符合.NET生态设计规范,也能兼容Serilog、NLog等第三方日志框架。
内容的提问来源于stack exchange,提问作者Tarun Lolla
相关产品推荐
相关产品推荐

