.NET中是否有基于W3C Trace Context自动创建Activity的中间件实现?
基于W3C traceparent头自动创建Activity的实现方案
一、无需额外第三方库,.NET原生支持
.NET的System.Diagnostics命名空间已经内置了W3C分布式追踪标准的适配能力,完全不需要依赖AppInsights或其他第三方工具。核心依赖类型包括Activity、ActivitySource和ActivityListener,足以实现需求。
二、推荐实现方式:自定义中间件
通过编写简单的中间件,即可自动读取请求头并创建Activity,步骤如下:
1. 定义全局ActivitySource
先在项目中声明一个全局的ActivitySource,作为追踪实例的标识:
public static class TelemetrySettings { public static readonly ActivitySource ServiceActivitySource = new ActivitySource("Your.Service.Identifier"); }
2. 编写追踪中间件
创建中间件类,处理traceparent头并初始化Activity:
public class TraceActivityMiddleware { private readonly RequestDelegate _next; public TraceActivityMiddleware(RequestDelegate next) { _next = next; } public async Task InvokeAsync(HttpContext context) { // 读取请求头中的traceparent var traceParentHeader = context.Request.Headers.TryGetValue("traceparent", out var headerValue) ? headerValue.ToString() : null; // 基于traceparent创建并启动Activity using var activity = TelemetrySettings.ServiceActivitySource.StartActivity( context.Request.Path, ActivityKind.Server, traceParentHeader); // 追加自定义追踪标签(可选) activity?.AddTag("http.method", context.Request.Method); activity?.AddTag("http.path", context.Request.Path); // 继续处理请求 await _next(context); // 根据响应状态更新Activity状态(可选) if (activity != null) { activity.SetStatus((int)context.Response.StatusCode is >= 200 and < 400 ? ActivityStatusCode.Ok : ActivityStatusCode.Error); activity.AddTag("http.status_code", context.Response.StatusCode); } } }
3. 注册中间件
在Program.cs中注册中间件,注意要放在路由相关中间件之前:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); var app = builder.Build(); // 注册追踪中间件 app.UseMiddleware<TraceActivityMiddleware>(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
三、可选:监听Activity生命周期
如果需要将追踪数据输出到日志或其他存储,可注册ActivityListener监听Activity的启停事件:
// 在Program.cs中添加 var traceListener = new ActivityListener { ShouldListenTo = source => source.Name == TelemetrySettings.ServiceActivitySource.Name, ActivityStarted = activity => { Console.WriteLine($"追踪启动:ID={activity.Id} | 路径={activity.DisplayName}"); }, ActivityStopped = activity => { Console.WriteLine($"追踪结束:ID={activity.Id} | 状态={activity.Status}"); foreach (var tag in activity.Tags) { Console.WriteLine($" 标签:{tag.Key} = {tag.Value}"); } } }; ActivitySource.AddActivityListener(traceListener);
四、替代方案:框架内置中间件
.NET 6+提供的UseHttpLogging中间件也能生成基础的请求Activity,但自定义中间件更灵活,可完全控制traceparent的解析逻辑和追踪标签的自定义。
内容的提问来源于stack exchange,提问作者Joel Lara
相关产品推荐
相关产品推荐

