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

.NET控制台应用依赖注入配置OpenTelemetry追踪的正确方法

.NET 9控制台应用依赖注入配置OpenTelemetry追踪的正确方法

核心问题分析

你遇到的ActivitySource._listeners为null的问题,本质是DI配置的OpenTelemetry追踪未被正确托管——TracerProvider没有完成初始化,导致你的ActivitySource没有关联到OTEL的监听者,自然无法导出追踪数据。手动用Sdk创建TracerProvider能临时解决,是因为手动触发了初始化,但违背了DI的生命周期管理逻辑。

正确配置步骤

1. 安装必要NuGet包

确保项目安装以下核心包:

OpenTelemetry.Extensions.Hosting
OpenTelemetry.Exporter.OpenTelemetryProtocol
OpenTelemetry.Exporter.Console // 用于本地调试

2. 配置DI中的OpenTelemetry追踪

在Program.cs中通过Host构建器配置OTEL,关键是让Host托管TracerProvider的生命周期,并关联你的ActivitySource:

var builder = Host.CreateDefaultBuilder(args);

builder.ConfigureServices(services =>
{
    // 配置OpenTelemetry追踪
    services.AddOpenTelemetry()
        .WithTracing(tracing =>
        {
            // 注册你的自定义ActivitySource名称(必须和代码中使用的一致)
            tracing.AddSource("OtelTestTracing.ActivitySource");
            
            // 本地调试用控制台导出器,方便验证数据生成
            tracing.AddConsoleExporter();
            
            // 配置OTLP导出到Docker中的收集器
            tracing.AddOtlpExporter(options =>
            {
                options.Endpoint = new Uri("http://localhost:4317"); // gRPC端口,若用HTTP则用4318
                options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
            });
            
            // 添加批量处理器,优化数据导出性能(可选但推荐)
            tracing.AddBatchExportProcessor<Activity>(new BatchExportProcessorOptions<Activity>
            {
                MaxQueueSize = 1024,
                ScheduledDelayMilliseconds = 500
            });
        });

    // 注入你的封装类
    services.AddSingleton<OtelTestTracing>();
});

var host = builder.Build();

// 获取封装类执行追踪逻辑
var tracingService = host.Services.GetRequiredService<OtelTestTracing>();
tracingService.RunTraceableTask();

// 控制台应用必须保持运行,否则Host会立即退出,OTEL来不及导出数据
await host.RunAsync();

3. 正确实现OtelTestTracing封装类

不要手动new ActivitySource后直接注入,而是让DI提供已被OTEL关联的实例:

public class OtelTestTracing
{
    private readonly ActivitySource _activitySource;

    // 注入ActivitySource,OTEL会自动关联监听者
    public OtelTestTracing(ActivitySource activitySource)
    {
        _activitySource = activitySource;
    }

    public void RunTraceableTask()
    {
        using var activity = _activitySource.StartActivity("SampleBusinessTask");
        if (activity == null) return;

        // 添加自定义标签
        activity.SetTag("task.id", Guid.NewGuid().ToString());
        activity.SetTag("task.status", "completed");

        // 模拟业务逻辑
        Thread.Sleep(100);
    }
}

关键注意事项

  • 保持Host运行:控制台应用必须调用await host.RunAsync(),否则Host启动后立即销毁,TracerProvider来不及初始化和导出数据。
  • ActivitySource名称一致:AddSource中注册的名称必须和ActivitySource实例的名称完全匹配,否则OTEL不会监听其生成的追踪。
  • 收集器端口验证:Docker中的OTEL收集器需正确映射端口(gRPC默认4317,HTTP默认4318),确保应用能访问到收集器地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:33:11