OpenTelemetry .NET内置Span正常但StartActiveSpan无效果问题
问题分析与解决
问题原因
你手动创建的Span无法被导出,核心问题在于你使用了全局默认的TracerProvider.Default来获取Tracer,而这个全局Provider并没有关联你通过AddOpenTelemetry配置的导出器(OtlpExporter)。你配置的TracerProvider是依赖注入容器中的独立实例,和全局Default Provider是两个不同的对象,导致手动创建的Span无法被传递到导出器,自然不会出现在追踪记录中。
解决方案
1. 修正Tracer的注册方式
移除原代码中直接使用TracerProvider.Default的注册行:
// 删掉这行 builder.Services.AddSingleton(TracerProvider.Default.GetTracer(serviceName));
替换为从DI容器中获取你配置的TracerProvider来创建Tracer:
builder.Services.AddSingleton(sp => { var tracerProvider = sp.GetRequiredService<TracerProvider>(); return tracerProvider.GetTracer(serviceName); });
2. 验证手动Span的上下文关联
确保你创建手动Span的代码是在HTTP请求上下文内部执行的(比如在Controller的Action、中间件或被请求触发的服务方法中),这样手动Span会自动关联AspNetCore创建的父Span,确保采样和链路传递正常。如果是在后台任务等无父上下文的场景创建Span,需要手动设置父上下文或确保采样器允许根Span被采集。
3. 可选:改用ActivitySource(推荐)
如果你使用的是OpenTelemetry .NET 1.0+版本,官方更推荐使用ActivitySource而非Tracer(Shim层API),示例如下:
定义ActivitySource
// 在类级别定义静态ActivitySource private static readonly ActivitySource _activitySource = new ActivitySource("web-ui");
创建Span
using var activity = _activitySource.StartActivity(nameof(CreateMarkdownComment));
配置时注册ActivitySource
在WithTracing中添加AddSource,指定你的ActivitySource名称:
.WithTracing( tracing => { tracing .AddAspNetCoreInstrumentation() .AddEntityFrameworkCoreInstrumentation(/* 你的配置 */) .AddSource("web-ui"); // 添加这行,注册你的ActivitySource // 导出器配置... })
验证修改
完成修改后重新启动应用,触发包含手动Span的业务逻辑,即可在Google Cloud Trace中看到手动创建的Span出现在链路追踪里。
内容的提问来源于stack exchange,提问作者Brad
相关产品推荐
相关产品推荐

