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

使用Microsoft.Extensions.Hosting与.NET472时Activity为Null的OpenTelemetry问题

问题

在使用Microsoft.Extensions.Hosting的.NET 4.7.2应用中集成OpenTelemetry时,按以下方式创建Host后,创建新Activity返回Null:

Host.CreateDefaultBuilder()
    .ConfigureServices((hostContext, services) =>
    {
        services.AddOpenTelemetry().WithTracing(tracerProviderBuilder =>
        {
            tracerProviderBuilder
                .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
                .AddConsoleExporter()
                .AddSource(serviceName);
        }).StartWithHost();
    })
    .Build();

对应的Activity创建代码:

var activitySource = new ActivitySource(serviceName);
using var activity = activitySource.StartActivity("Hello");

但直接使用Sdk.CreateTracerProviderBuilder方式注册则能正常运行:

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
    .AddSource(serviceName)
    .AddConsoleExporter()
    .Build();

请问如何在第一种Host创建方式下,获取带有已配置监听器的ActivitySource?


解决方案

核心问题是:通过Host注册的OpenTelemetry TracerProvider,需要Host实际启动后才会初始化生效。你在Host Build完成后直接创建Activity时,Host还未启动,TracerProvider尚未激活,导致ActivitySource没有被监听,StartActivity返回Null。

按以下步骤修改即可解决:

1. 确保Host完成启动

调用host.Run()或host.Start()启动Host,再执行创建Activity的逻辑。

2. 通过依赖注入管理ActivitySource

不要手动实例化ActivitySource,将其注册为DI容器中的单例,确保和OpenTelemetry配置的源完全匹配,之后通过构造函数注入使用。

修改后的完整代码示例

注册服务与启动Host

Host.CreateDefaultBuilder()
    .ConfigureServices((hostContext, services) =>
    {
        // 将ActivitySource注册为单例服务
        services.AddSingleton(new ActivitySource(serviceName));
        
        services.AddOpenTelemetry().WithTracing(tracerProviderBuilder =>
        {
            tracerProviderBuilder
                .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
                .AddConsoleExporter()
                .AddSource(serviceName);
        }).StartWithHost();
        
        // 添加后台服务用于测试Activity逻辑(或在Host启动后执行你的业务代码)
        services.AddHostedService<ActivityTestService>();
    })
    .Build()
    .Run(); // 启动Host,此时TracerProvider会被初始化

后台服务中使用ActivitySource

public class ActivityTestService : IHostedService
{
    private readonly ActivitySource _activitySource;

    // 通过构造函数注入ActivitySource
    public ActivityTestService(ActivitySource activitySource)
    {
        _activitySource = activitySource;
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 此时Host已启动,TracerProvider已激活,Activity可正常创建
        using var activity = _activitySource.StartActivity("Hello");
        activity?.SetTag("business-id", "12345");
        
        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }
}

额外注意事项

  • .StartWithHost()方法会将TracerProvider的生命周期与Host绑定,Host启动时初始化TracerProvider,停止时自动销毁。
  • 禁止在Host.Build()之后、Run/Start()之前执行创建Activity的逻辑,此时TracerProvider还未完成初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:05:35