.Net Core 项目如何获取 Skywalking 中的 traceId?
SkyAPM.Agent.AspNetCore 1.1.0 获取Trace ID实现方案
下面是两种经过验证的可行实现方案:
方案1:依赖注入ISkyWalkingContext获取(最稳定,官方原生支持)
1.1.0版本的Agent启动时会自动将上下文服务注入到ASP.NET Core的DI容器中,无需额外配置,直接注入使用即可:
- 业务类构造函数中注入
ISkyWalkingContext接口 - 直接读取接口的
TraceId属性即可拿到当前请求对应的链路Trace ID
代码示例:
using SkyAPM.Agent.AspNetCore; using Microsoft.AspNetCore.Mvc; public class BusinessController : ControllerBase { private readonly ISkyWalkingContext _skyWalkingContext; public BusinessController(ISkyWalkingContext skyWalkingContext) { _skyWalkingContext = skyWalkingContext; } [HttpGet("test")] public IActionResult TestTraceId() { // 直接获取当前请求Trace ID string currentTraceId = _skyWalkingContext.TraceId; // 此处写入你需要的业务逻辑,比如关联日志、业务单据打标等 return Ok(new { TraceId = currentTraceId }); } }
注意:只有当前请求被SkyAPM链路采集的场景下才能拿到有效值,未被采集的请求会返回空字符串;异步请求上下文场景下可以正常取值,无需额外处理跨线程传递。
方案2:解析请求Header获取(无需依赖SkyAPM专属接口)
如果你的服务是上游调用的下游节点,SkyWalking的链路信息会通过Header透传,你可以直接解析sw8Header拿到Trace ID,适合不想在业务层引用SkyAPM包的场景:
- 1.1.0版本对应SkyWalking v8协议,链路Header固定为
sw8,值的格式为{采样标记}-{Base64编码的TraceId}-{SegmentId}-{SpanId}-{父实例ID}-{父服务名}-{父端点}-{父地址},用-分割 - 取第二个分段做Base64解码即可拿到明文Trace ID
代码示例:
[HttpGet("test")] public IActionResult TestTraceId() { string traceId = string.Empty; if (Request.Headers.TryGetValue("sw8", out var sw8Header)) { var segments = sw8Header.ToString().Split('-'); if (segments.Length >= 2) { traceId = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(segments[1])); } } return Ok(new { TraceId = traceId }); }
异常排查
- 若取值为空,先确认SkyAPM Agent配置正确,
SkyAPM__Transport__gRPC__Servers地址可达,服务启动日志无SkyAPM相关报错 - 不要在请求结束后的异步回调中获取Trace ID,此时请求上下文已经释放,会返回空值
内容的提问来源于stack exchange,提问作者Charlie
相关产品推荐
相关产品推荐

