.NET Core API中Serilog+App Insights日志配置及关联ID咨询
我刚好处理过类似的.NET Core API日志场景,结合Serilog和App Insights的同时,要保留框架自带跟踪事件、传递关联ID并实现端到端跟踪,其实只需要几个关键配置步骤,下面给你详细拆解:
一、让.NET Core框架跟踪事件发送至App Insights
即使你改用Serilog处理应用日志,依然可以保留.NET Core自身的跟踪事件(比如ASP.NET Core的请求管道日志、依赖跟踪等)发送到App Insights,核心是不要移除Microsoft.ApplicationInsights.AspNetCore包,并且正确配置Telemetry服务:
确保安装必要的NuGet包:
Install-Package Microsoft.ApplicationInsights.AspNetCore Install-Package Serilog.Sinks.ApplicationInsights Install-Package Serilog.AspNetCore在
Program.cs中先初始化Application Insights Telemetry服务,再配置Serilog:var builder = WebApplication.CreateBuilder(args); // 第一步:添加Application Insights服务,自动收集框架跟踪事件 builder.Services.AddApplicationInsightsTelemetry(); // 第二步:配置Serilog,将应用日志写入App Insights builder.Host.UseSerilog((context, services, configuration) => configuration .ReadFrom.Configuration(context.Configuration) .ReadFrom.Services(services) .Enrich.FromLogContext() .WriteTo.ApplicationInsights( services.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces)); // 后续的API服务配置... var app = builder.Build();
这样配置后,.NET Core框架生成的跟踪事件(比如路由匹配、中间件执行日志)会通过Application Insights Telemetry服务自动发送到App Insights,而你的应用日志则通过Serilog统一写入。
二、将自定义关联ID(Correlation Id)传递给.NET Core跟踪事件
要让框架生成的跟踪事件带上你自定义的关联ID,需要通过自定义Telemetry初始化器来实现,同时确保Serilog日志也包含这个关联ID:
安装Serilog关联ID增强包(如果还没装):
Install-Package Serilog.Enrichers.CorrelationId创建自定义Telemetry初始化器,提取HttpContext中的关联ID并附加到Telemetry的操作上下文:
public class CorrelationIdTelemetryInitializer : ITelemetryInitializer { private readonly IHttpContextAccessor _httpContextAccessor; public CorrelationIdTelemetryInitializer(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public void Initialize(ITelemetry telemetry) { var httpContext = _httpContextAccessor.HttpContext; if (httpContext == null) return; // 从HttpContext中获取自定义关联ID(这里假设你用X-Correlation-ID头传递) if (httpContext.Request.Headers.TryGetValue("X-Correlation-ID", out var correlationId)) { telemetry.Context.Operation.Id = correlationId; // 也可以设置Operation.Name,方便在App Insights中识别 telemetry.Context.Operation.Name = httpContext.Request.Path; } } }在
Program.cs中注册这个初始化器,并配置Serilog启用关联ID增强:var builder = WebApplication.CreateBuilder(args); // 添加HttpContextAccessor,用于获取请求上下文 builder.Services.AddHttpContextAccessor(); // 注册自定义Telemetry初始化器 builder.Services.AddSingleton<ITelemetryInitializer, CorrelationIdTelemetryInitializer>(); // 添加Application Insights服务 builder.Services.AddApplicationInsightsTelemetry(); // 配置Serilog,启用关联ID增强 builder.Host.UseSerilog((context, services, configuration) => configuration .ReadFrom.Configuration(context.Configuration) .ReadFrom.Services(services) .Enrich.FromLogContext() .Enrich.WithCorrelationId(headerName: "X-Correlation-ID") // 从请求头提取关联ID .WriteTo.ApplicationInsights( services.GetRequiredService<TelemetryConfiguration>(), TelemetryConverter.Traces)); // 后续配置...
这样,无论是Serilog生成的应用日志,还是.NET Core框架生成的跟踪事件,都会带上同一个X-Correlation-ID的值,在App Insights中可以通过这个ID过滤所有相关的日志条目。
三、端到端跟踪的关键配置
要实现跨服务的端到端跟踪,除了上面的关联ID传递,还要确保以下几点:
- 统一关联ID传递规则:所有服务之间的调用都通过同一个HTTP头(比如
X-Correlation-ID)传递关联ID,下游服务接收后同样用上面的Telemetry初始化器将其设置为操作ID。 - 启用Application Insights分布式跟踪:在
appsettings.json中确保Application Insights的分布式跟踪配置开启:"ApplicationInsights": { "InstrumentationKey": "你的InstrumentationKey", "EnableDependencyTracking": true, "EnableRequestTracking": true, "DistributedTracingEnabled": true } - 确保Serilog日志包含关联ID:在Serilog的输出模板中添加
{CorrelationId},比如在appsettings.json中配置:"Serilog": { "MinimumLevel": "Information", "WriteTo": [ { "Name": "ApplicationInsights", "Args": { "telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverter+Traces, Serilog.Sinks.ApplicationInsights" } } ], "Enrich": [ "FromLogContext", "WithCorrelationId" ], "Properties": { "Application": "你的API名称" }, "OutputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {CorrelationId} {Message:lj}{NewLine}{Exception}" }
通过以上配置,你可以在App Insights的“搜索”或“事务搜索”功能中,输入关联ID就能查看整个请求链路中所有服务的日志和跟踪事件,实现完整的端到端跟踪。
内容的提问来源于stack exchange,提问作者frosty

