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

Serilog写入Azure App Insights时日志级别映射异常问题排查

问题:Serilog日志写入Azure Application Insights时级别映射异常

我用Serilog把日志写入Azure Application Insights,发现错误、警告等日志都以**严重级别1(对应App Insights的信息级别)**记录。预期应该是错误对应级别3、严重错误对应级别4、警告对应级别2,但现在所有日志统一为级别1。


相关配置详情

App.settings.json 配置

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.ApplicationInsights", "Serilog.Sinks.Console" ],
    "MinimumLevel": {
      "Default": "Information",
      "Override": {
        "Microsoft": "Warning",
        "Microsoft.Hosting.Lifetime": "Warning",
        "System": "Error"
      }
    },
    "Enrich": [ "FromLogContext", "WithExceptionDetails", "WithCustomContext", "WithEnvironmentUserName", "WithMachineName", "WithProcessId", "WithThreadId" ],
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
          "restrictedToMinimumLevel": "Information",
          "outputTemplate": "[{Timestamp:G}] [{Level:u3}] *** [{SourceContext}] *** {Message:lj} | {NewLine:1}{Exception:1}"
        }
      },
      {
        "Name": "ApplicationInsights",
        "Args": {
          "instrumentationKey": "xxxxxxxxxxxxxxxxxxxxxxx",
          // "restrictedToMinimumLevel": "Information",
          "outputTemplate": "[{Timestamp:G}] [{Level:u3}] *** [{SourceContext}] *** {Message:lj} | {Properties}{NewLine:1}{Exception:1}",
          "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights"
        }
      }
    ]
  }
}

Program.cs 代码

using Serilog;
using ILogger = Serilog.ILogger;

var envrironment = string.Empty;
var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(worker =>
    {
        worker.UseNewtonsoftJson();
           
    }).ConfigureServices(services =>
    {
        services.AddLocalClients();
              
        services.AddSingleton<ILogger>(Log.Logger);


    }).ConfigureAppConfiguration(configBuilder =>
    {
        configBuilder.AddCustomConfiguration();
    })
    .ConfigureLogging((hostingContext, logging) =>
    {
        logging.AddSerilogProvider(hostingContext);
    });
host.Build().Run();

LogBuilderExtension.cs 代码

internal static class LogBuilderExtension
{
    public static void AddSerilogProvider(this ILoggingBuilder logBuilder, HostBuilderContext hostingContext, Action<LoggerConfiguration>? configureLogger = null)
    {

        var loggerConfiguration = new LoggerConfiguration()
            .ReadFrom.Configuration(hostingContext.Configuration)
            .Enrich.WithProperty("cloud_RoleName", hostingContext.Configuration["WEBSITE_SITE_NAME"])
            .Enrich.WithCustomContext();

        configureLogger?.Invoke(loggerConfiguration);
        var logger = loggerConfiguration.CreateLogger();

        logBuilder.ClearProviders();
        logBuilder.AddSerilog(logger, true);
    }
}

日志级别显示异常截图

App Insights中所有日志级别均为1的截图

LoggerExtension 相关代码

public class LoggerExtension : ILogEventEnricher
{
    private const string ClassName = "ClassName";
    private const string MethodName = "MethodName";
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        if (logEvent.Properties.TryGetValue("SourceContext", out var sourceContextProperty))
        {
            var classNameProperty = new LogEventProperty(ClassName, sourceContextProperty);
            logEvent.AddPropertyIfAbsent(classNameProperty);

        }
        if (logEvent.Properties.TryGetValue("AzureFunctions_FunctionName", out var actionNameProperty))
        {
            var methodNameProperty = new LogEventProperty(MethodName, actionNameProperty);
            logEvent.AddPropertyIfAbsent(methodNameProperty);

        }
    }
}

public static class SerilogExtensions
{
    public static LoggerConfiguration WithCustomContext(this LoggerEnrichmentConfiguration enrichmentConfiguration)
    {
        return enrichmentConfiguration.With(new LoggerExtension());
    }

}

解决方案

问题根源在你用的TraceTelemetryConverter——这个转换器默认把所有Serilog日志都转成TraceTelemetry,而TraceTelemetry在App Insights里默认SeverityLevel就是Information(级别1),不会根据Serilog的日志级别自动映射。

修正配置

把App.settings.json里ApplicationInsights的telemetryConverter换成以下两种之一:

  1. 自动映射所有级别:用ApplicationInsightsTelemetryConverter,它会根据Serilog的日志级别自动对应到App Insights的SeverityLevel
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.ApplicationInsightsTelemetryConverter, Serilog.Sinks.ApplicationInsights"
  1. 区分Trace和Exception日志:用TraceAndExceptionTelemetryConverter,带Exception的日志会转成ExceptionTelemetry(对应Error级别),其他日志自动映射级别
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceAndExceptionTelemetryConverter, Serilog.Sinks.ApplicationInsights"

级别对应关系

Serilog日志级别 ↔ App Insights SeverityLevel:

  • Verbose/Debug → Verbose(0)
  • Information → Information(1)
  • Warning → Warning(2)
  • Error → Error(3)
  • Fatal → Critical(4)

额外检查

  • 确保Serilog.Sinks.ApplicationInsights包是最新版本,旧版本可能存在映射bug
  • 确认代码里调用了正确的日志方法,比如用Log.Error()写错误日志、Log.Warning()写警告日志,而非统一用Log.Information()

内容的提问来源于stack exchange,提问作者suraj_123

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:24:51