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

.NET6.0 ASPCore应用向Grafana Tempo发送追踪数据的方案咨询

问题背景

我已经为这个问题折腾了两天,现有一个.NET 6.0 Web应用,需要将追踪数据发送到Grafana Tempo实例。目前应用已经配置了Jaeger作为追踪组件,现在要替换成Grafana Tempo,但尝试的所有方法都没成功,希望得到帮助。

已尝试的方案

  1. 调研实现方案

.NET有可与OpenTelemetry配合的库,但原本以为只需要OpenTracing即可,因为Tempo应该直接兼容Jaeger(Jaeger基于OpenTracing构建)。

  1. 尝试修改Jaeger端点
    因为Jaeger支持OpenTracing,我尝试直接替换其端点,但未成功。代码如下:
services.AddOpenTracing();
// Adds the Jaeger Tracer.
services.AddSingleton<ITracer>(sp =>
{
    var loggerFactory = sp.GetRequiredService<ILoggerFactory>();
    var reporter = new RemoteReporter.Builder()
        .WithLoggerFactory(loggerFactory)
        .WithSender(new HttpSender("http://localhost:9411"))
        .Build();
    var tracer = new Tracer.Builder(_serviceName)
        // The constant sampler reports every span.
        .WithSampler(new ConstSampler(true))
        // LoggingReporter prints every reported span to the logging framework.
        .WithReporter(reporter)
        .Build();
    return tracer;
});

services.Configure<HttpHandlerDiagnosticOptions>(options =>
    options.OperationNameResolver =
        request => $"{request.Method.Method}: {request?.RequestUri?.AbsoluteUri}");

业务代码中手动创建Span的逻辑:

using var scope = Tracer.BuildSpan(ControllerContext.ActionDescriptor.DisplayName)
    .StartActive(true);

Console.WriteLine(scope.Span.Context.TraceId);

scope.Span.Log("Requested all observation metadata");
  1. 尝试OpenTelemetry方案
    我发现很多NuGet包只有预览版,文档显示需要用OTelCollector,但关于如何创建并连接到Tempo的说明很模糊。我跳过了Collector,尝试直接配置,但也没成功:
var serviceName = "Grafana.Tempo.POC.API";
var serviceVersion = "1.0.0";

// Configure important OpenTelemetry settings, the console exporter, and instrumentation library
builder.Services.AddOpenTelemetryTracing(
    tracerProviderBuilder =>
    {
        tracerProviderBuilder
            .AddConsoleExporter()
            .AddSource(serviceName)
            .SetResourceBuilder(
                ResourceBuilder.CreateDefault()
                    .AddService(serviceName: serviceName, serviceVersion: serviceVersion)
            )
            .AddHttpClientInstrumentation()
            .AddAspNetCoreInstrumentation()
            .AddSqlClientInstrumentation()
            .AddOtlpExporter(
                options =>
                {
                    options.Endpoint =
                        new Uri("http://localhost:9411");
                }
            );
    }
);
  1. Curl测试成功
    查阅Grafana文档后测试了Curl示例,首次成功将追踪数据发送到Tempo,但手动调用API不适合实际开发:
curl -X POST http://localhost:9411 -H 'Content-Type: application/json' -d '[{
 "id": "1234",
 "traceId": "0123456789abcdef",
 "timestamp": 1608239395286533,
 "duration": 100000,
 "name": "span from bash!",
 "tags": {
    "http.method": "GET",
    "http.path": "/api"
  },
  "localEndpoint": {
    "serviceName": "shell script"
  }
}]'

核心问题

  1. 从ASP.NET Core应用向Grafana Tempo发送追踪数据,最实用且简便的方案是什么?
  2. 是否可以直接使用Jaeger并仅修改配置重定向至Tempo?是否有其他配置选项可用?
  3. 是否必须使用OpenTelemetry Collector才能实现该功能?

补充环境:当前使用Win11、WSL2、Docker Desktop及.NET6.0测试,后续计划部署到Kubernetes环境。


解决方案

1. 最实用简便的方案:基于OpenTelemetry直接对接Tempo

推荐使用稳定版OpenTelemetry包对接Tempo,这是当前规范且长期维护的方案,步骤如下:

  • 安装稳定NuGet包:无需使用预览版,安装以下正式版包:
    • OpenTelemetry.Extensions.Hosting
    • OpenTelemetry.Instrumentation.AspNetCore
    • OpenTelemetry.Instrumentation.Http
    • OpenTelemetry.Exporter.OpenTelemetryProtocol
  • 修正OTLP配置:Tempo的OTLP HTTP默认端点为http://localhost:4318/v1/traces(之前用的9411是Zipkin端口,属于关键错误),调整配置代码:
var serviceName = "Grafana.Tempo.POC.API";
var serviceVersion = "1.0.0";

builder.Services.AddOpenTelemetryTracing(builder =>
{
    builder
        .AddConsoleExporter()
        .AddSource(serviceName)
        .SetResourceBuilder(
            ResourceBuilder.CreateDefault()
                .AddService(serviceName, serviceVersion)
        )
        .AddAspNetCoreInstrumentation()
        .AddHttpClientInstrumentation()
        .AddSqlClientInstrumentation()
        .AddOtlpExporter(options =>
        {
            options.Endpoint = new Uri("http://localhost:4318/v1/traces");
            options.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.HttpProtobuf;
        });
});
  • 手动创建Span的适配:推荐用ActivitySource替代旧的OpenTracing方式,更符合OTel规范:
private static readonly ActivitySource _activitySource = new ActivitySource("Grafana.Tempo.POC.API");

// 在控制器方法中
using var activity = _activitySource.StartActivity(ControllerContext.ActionDescriptor.DisplayName);
activity?.SetTag("http.method", HttpContext.Request.Method);
activity?.AddEvent(new ActivityEvent("Requested all observation metadata"));

2. 可以直接用Jaeger重定向到Tempo,需修正端点与配置

Jaeger可直接对接Tempo,之前失败是因为用错了端点:

  • 修正Jaeger端点:Tempo默认监听Jaeger HTTP协议的端口为14268,修改HttpSender配置:
var reporter = new RemoteReporter.Builder()
    .WithLoggerFactory(loggerFactory)
    .WithSender(new HttpSender("http://localhost:14268/api/traces")) // 修正端点
    .Build();
  • 确保Tempo开启Jaeger接收器:Docker启动时需开启对应接收器,命令示例:
docker run -d -p 14268:14268 -p 4318:4318 grafana/tempo:latest --config.file=/etc/tempo-local.yaml

若用自定义配置文件,需明确启用Jaeger接收器:

receivers:
  jaeger:
    protocols:
      thrift_http:
        endpoint: 0.0.0.0:14268

3. 不需要必须使用OpenTelemetry Collector

直接从应用发送数据到Tempo完全可行,Collector仅在以下场景需要:

  • 同时向多个后端发送追踪数据
  • 需要对追踪数据进行预处理(采样、过滤、转换)
  • 应用与Tempo存在网络隔离
    你的场景下,不管用Jaeger直接对接还是OTel直接对接,都可以跳过Collector。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 03:16:26