.NET ILogger LogError写入Application Insights被记为Information级别
问题说明
本问题非同类帖子重复问题,现有公开方案无法解决对应异常。场景为.NET 6.0控制台应用接入Application Insights,基础配置代码如下:
using var channel = new InMemoryChannel(); try { IServiceCollection services = new ServiceCollection(); services.Configure<TelemetryConfiguration>(config => config.TelemetryChannel = channel); services.AddLogging(builder => { builder.AddFilter<ApplicationInsightsLoggerProvider>("Microsoft", LogLevel.Error); builder.AddApplicationInsights("000000-0000-0000-0000-1111111"); builder.AddFilter<ApplicationInsightsLoggerProvider>("", LogLevel.Information); }); IServiceProvider serviceProvider = services.BuildServiceProvider(); ILogger<Program> logger = serviceProvider.GetRequiredService<ILogger<Program>>(); var now = DateTime.UtcNow; logger.LogInformation("Logger is working... {Now}", now); logger.LogError("Logger is issuing an error {Now}", now); logger.LogWarning("Logger is issuing a warning {Now}", now); logger.LogError(new Exception("Some ficititious exception"), "This is an exception messsage {Now}", now); } finally { // 控制台应用需显式调用Flush加延迟,确保应用退出前遥测数据全部上报 channel.Flush(); await Task.Delay(TimeSpan.FromMilliseconds(1000)); }
异常现象:
- 所有日志均可正常上报到Application Insights平台
- 无异常参数的
logger.LogError("Logger is issuing an error {Now}", now);调用,在平台被错误标记为Information级别 - 携带Exception对象的
LogError调用日志级别显示正常 - Information、Warning级别日志上报级别无异常
排查思路与修复方案
按优先级从高到低依次排查:
1. 检查依赖包引用正确性
控制台场景不要只手动引用基础Microsoft.ApplicationInsights包,必须替换安装Microsoft.ApplicationInsights.WorkerService包,前者没有内置完整的ILogger级别映射适配逻辑,手动拼凑依赖很容易出现日志级别转换异常。
2. 排除SDK版本已知Bug
2.20~2.21区间版本的Application Insights SDK存在明确的映射缺陷:无Exception参数传入的LogError/LogCritical调用,会被SDK内部错误映射为Information级别,只有携带异常对象的错误日志才会走正确的级别映射逻辑。
- 优先方案:升级SDK到2.22及以上稳定版本
- 临时兼容方案:如果暂时无法升级SDK,添加自定义遥测初始化器强制修正级别,代码如下:
public class CorrectLogLevelTelemetryInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (telemetry is not TraceTelemetry trace) return; if (trace.Properties.TryGetValue("LogLevel", out var rawLogLevel) && Enum.TryParse<LogLevel>(rawLogLevel, out var originalLogLevel)) { trace.SeverityLevel = originalLogLevel switch { LogLevel.Trace or LogLevel.Debug => SeverityLevel.Verbose, LogLevel.Information => SeverityLevel.Information, LogLevel.Warning => SeverityLevel.Warning, LogLevel.Error => SeverityLevel.Error, LogLevel.Critical => SeverityLevel.Critical, _ => trace.SeverityLevel }; } } }
注册初始化器到DI容器即可生效:
services.AddSingleton<ITelemetryInitializer, CorrectLogLevelTelemetryInitializer>();
3. 修正日志过滤器注册顺序与写法
.NET日志过滤器遵循「后注册优先级更高」的规则,不要多次针对ApplicationInsightsLoggerProvider拆分注册过滤器,也不要使用AddApplicationInsights方法内传入默认日志级别的旧重载,避免内置默认规则覆盖自定义配置。推荐配置写法如下:
services.AddLogging(builder => { // 先注册Application Insights日志提供程序 builder.AddApplicationInsights("你的 instrumentation key"); // 按从特殊到通用的顺序注册过滤规则 builder.AddFilter("Microsoft", LogLevel.Error); builder.AddFilter("", LogLevel.Information); });
4. 排查平台侧配置问题
进入Application Insights工作区的日志查询页,直接查询traces表原始数据,查看severityLevel字段值:
- 如果原始字段值为3(对应Error级别),说明是门户视图的筛选规则、字段映射配置异常,重置视图筛选条件即可
- 如果原始字段值为1(对应Information级别),说明问题出在应用侧上报环节,按前面三个方案修复即可。
内容的提问来源于stack exchange,提问作者Arash
相关产品推荐
相关产品推荐

