在分布式追踪的配置里,有个问题特别常见:明明代码里调了 StartActivity(),可 Jaeger 或者 Zipkin 那边就是干干净净,一条数据都收不到。这种时候,不用怀疑自己是不是写错了,八成是底层那几个关键组件没配好。

C#怎么创建分布式追踪_C# OpenTelemetry Tracing配置教程【高级】

为什么直接用 OpenTelemetry.Sdk 会收不到 trace?

问题出在哪儿?其实很简单,就是默认配置下,TracerProvider 既没注册 ActivitySource,也没启用导出器(exporter)。你创建出来的 Activity 就像个没家的孩子,没人管,也没人把它送出去,自然就被丢弃了。

核心就在于,你得把这三样东西显式地组装起来,少一个都不行:

一个典型的配置片段如下:

var builder = Sdk.CreateTracerProviderBuilder()
    .AddSource("my-api") // 和 new ActivitySource("my-api") 对应
    .AddOtlpExporter(opt => opt.Endpoint = new Uri("http://localhost:4317")); // 必须设 endpoint

ASP.NET Core 6+ 中如何自动注入 Activity 并关联 HTTP 上下文?

很多人会习惯性地在每个 Controller 里手动写 StartActivity(),其实大可不必。OpenTelemetry.Instrumentation.AspNetCore 这个包已经帮你把 HTTP 入口的自动埋点做好了,前提是你得把它加到 TracerProvider 里。

这里有三个容易漏掉的地方,你得留个心眼:

不然的话,你会看到 Controller 方法里自己创建的 span 有数据,但最关键的 HTTP 请求本身的 root span 却缺失了,整个链路在入口处就断了,分析起来非常头疼。

ActivitySource 命名不一致会导致 trace 断裂吗?

会的,而且这个问题非常隐蔽。OpenTelemetry 的采样、资源标注,甚至 exporter 的过滤,都依赖 ActivitySource.Name。你要是代码里写 new ActivitySource("order-service"),但 TracerProvider 只注册了 AddSource("orderservice"),那么所有从这个 source 发出的 span 都会静默丢失,找都找不到原因。

为了避免这种问题,建议统一规范:

本地调试时 trace 总是延迟 10 秒才上报?

这是个很典型的“开发体验问题”。OtlpExporter 默认的 batch 处理行为是:攒够 512 条数据,或者等满 10 秒,才发一次。在开发阶段,这几乎等于“看不到实时 trace”,非常影响调试效率。

解决方法很简单,就是在配置 exporter 时,显式地调小这些参数:

.AddOtlpExporter(opt =>
{
    opt.Endpoint = new Uri("http://localhost:4317");
    opt.BatchExportProcessorOptions = new BatchExportActivityProcessorOptions
    {
        ExporterTimeoutMilliseconds = 3000,
        MaxExportBatchSize = 1,
        ScheduledDelayMilliseconds = 100
    };
});

注意:MaxExportBatchSize = 1 虽然能带来最“实时”的体验,但会显著增加网络请求次数,这招只适合在调试时用。生产环境下,建议还是保留默认值,或者设为 512。

另外,也别忘了检查一下后端接收服务(比如 otel-collector)是否已经启动,并且端口是可达的。很多人在排查时忽略了 HttpRequestException 这类错误,其实 exporter 连不上时,它只会默默降级,根本不会抛异常出来,所以数据出不来,你都不知道是哪里卡住了。

本文转载于:https://www.php.cn/faq/2342140.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。