Envoy OpenTelemetry Tracer 新增 set_instrumentation_scope 配置:控制 trace 中 Instrumentation Scope 名称与版本的输出
2026/9/17 4:06:38 网站建设 项目流程

Envoy OpenTelemetry Tracer 新增 set_instrumentation_scope 配置:控制 trace 中 Instrumentation Scope 名称与版本的输出

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

导读

本文围绕 Envoy 仓库 changelog 中记录的tracing: added set_instrumentation_scope option to the OpenTelemetry tracer新特性展开,介绍该配置项在 OpenTelemetryConfig 中的位置、默认行为、底层实现与测试验证方式。读完本文,你将掌握如何通过set_instrumentation_scope控制 Envoy 向 OTLP 后端导出的 trace 中是否携带 instrumentation scope 名称("envoy")与 Envoy 版本号,以及该能力在链路可观测性数据语义上的实际影响。

一、功能背景:什么是 Instrumentation Scope

在 OpenTelemetry 规范中,trace 数据以ResourceSpans -> ScopeSpans -> Span的层级组织:一个ResourceSpans描述来源资源(如服务名、SDK 信息),其下包含多个ScopeSpans,每个ScopeSpans携带一个可选的 instrumentation scope 信息以及若干 span。instrumentation scope 用于标识产生这些 span 的检测库(如库名 "envoy" 及其版本),是后端系统判断 trace 数据来源、进行版本归因与排障的重要元数据。

在 Envoy 的 OpenTelemetry tracer 中,此前导出的 OTLP 请求中 scope 名称与版本是固定写入的。本次变更新增set_instrumentation_scope配置项,让用户能够决定是否在导出的 trace 中发射该 scope 信息,从而满足不同后端对数据体积与字段语义的差异化要求。

二、配置项定义与默认行为

该配置项定义在 OpenTelemetry tracer 的 API 中:api/envoy/config/trace/v3/opentelemetry.proto:

// Specifies whether to set the instrumentation scope name ("envoy") and version on emitted traces. // If not specified, the default is to set the instrumentation scope name and version. google.protobuf.BoolValue set_instrumentation_scope = 9;

要点如下:

  • 字段类型为google.protobuf.BoolValue(三态布尔),字段号为9
  • 注释明确指出:该字段控制是否在发射的 trace 上设置 instrumentation scope 名称(固定为"envoy")与版本;
  • 未配置时默认行为是设置 scope 名称与版本(即默认等价于true);
  • 该字段属于OpenTelemetryConfig消息,与grpc_servicehttp_serviceexporterservice_nameresource_detectorssamplermax_cache_sizeset_telemetry_sdk_resource_attributesset_service_name_resource_attribute等字段并列(消息当前#next-free-field: 11)。

值得一提的是,该配置与同消息中的set_telemetry_sdk_resource_attributes(字段 7,控制telemetry.sdk.language/name/version资源属性)和set_service_name_resource_attribute(字段 8,控制service.name资源属性)在语义上是一组"是否写入 OTel 元数据"的可选开关,set_instrumentation_scope补齐了 scope 层面的控制能力。

三、配置示例

在 bootstrap 配置的tracing段中,可以像下面这样显式关闭 scope 名称与版本的输出(该示例结构参考了仓库测试中的配置写法,见 opentelemetry_tracer_impl_test.cc):

tracing: http: name: envoy.tracers.opentelemetry typed_config: "@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig grpc_service: envoy_grpc: cluster_name: opentelemetry-collector timeout: 0.250s service_name: my-service set_instrumentation_scope: false
  • 省略set_instrumentation_scope字段,或显式设为true,都会在导出的 trace 中写入 scope 名称与版本;
  • 设为false时,ScopeSpans中的 scope 保持为空对象(scope: {}),不再包含名称与版本。

四、源码实现原理

4.1 配置解析与默认值注入

配置在 opentelemetry_tracer_impl.cc 中被解析为 C++ 布尔值:

const uint64_t max_cache_size = PROTOBUF_GET_WRAPPED_OR_DEFAULT(opentelemetry_config, max_cache_size, DEFAULT_MAX_CACHE_SIZE); const bool set_instrumentation_scope = PROTOBUF_GET_WRAPPED_OR_DEFAULT(opentelemetry_config, set_instrumentation_scope, true);

PROTOBUF_GET_WRAPPED_OR_DEFAULT宏的语义是:若BoolValue字段已设置则取其值,否则使用默认值true,与 proto 注释中"默认设置"的行为一致。

4.2 值传递到 TLS 中的 Tracer

解析出的布尔值随后被捕获进 TLS(Thread Local Storage)初始化回调(opentelemetry_tracer_impl.cc),并传入Tracer构造函数。Tracer构造函数签名在 tracer.h 中同样声明了默认值bool set_instrumentation_scope = true,且内部成员以const bool set_instrumentation_scope_{true};存储(tracer.h),保证未显式传入时行为一致。

4.3 导出发射时的条件写入

真正决定是否写入 scope 的逻辑位于 span 批量导出方法flushSpans()中:tracer.cc:

::opentelemetry::proto::trace::v1::ScopeSpans* scope_span = resource_span->add_scope_spans(); if (set_instrumentation_scope_) { // set the instrumentation scope name and version *scope_span->mutable_scope()->mutable_name() = "envoy"; *scope_span->mutable_scope()->mutable_version() = Envoy::VersionInfo::version(); } for (const auto& pending_span : span_buffer_) { (*scope_span->add_spans()) = pending_span; }

即:

  • 每个ResourceSpans下总会创建一个ScopeSpans容器用于承载批量 span;
  • 仅当set_instrumentation_scope_true时,才会向ScopeSpans.scope填充:
    • name:固定字符串"envoy"
    • version:当前 Envoy 的版本号,取自Envoy::VersionInfo::version()(定义于source/common/version/version.h,对应VERSION.txt中的发布版本);
  • false时,scope保持为空消息,导出数据不携带名称与版本。

从实现细节还可以看到,该导出流程与ResourceSpans的资源属性(service.name等)、schema_url的写入相互独立,因此关闭 scope 输出不会影响资源属性等其他元数据。

五、测试验证:关闭后 scope 为空对象

仓库通过单元测试对该行为进行了验证,见 opentelemetry_tracer_impl_test.cc,测试用例SetInstrumentationScopeFalse

  1. 加载如下配置并创建 Driver:
grpc_service: envoy_grpc: cluster_name: fake-cluster timeout: 0.250s set_instrumentation_scope: false
  1. 启动一个 span 并finishSpan()触发导出,随后用Grpc::ProtoBufferEqIgnoreRepeatedFieldOrdering断言发送到 mock gRPC client 的请求内容。

  2. 期望的导出请求(YAML 形式)中,scope_spansscope为空对象:

resource_spans: resource: attributes: key: "service.name" value: string_value: "unknown_service:envoy" key: "key1" value: string_value: "val1" scope_spans: scope: {{}} spans: name: "test" kind: SPAN_KIND_SERVER ...

该测试同时印证了两点:

  • set_instrumentation_scope: false时,导出的ScopeSpans.scope确为空对象(scope: {}),不包含 "envoy" 名称与版本;
  • 同一条请求中service.name资源属性仍正常输出,说明关闭 scope 不影响 Resource 级别的属性写入。

此外测试断言导出后计数器tracing.opentelemetry.spans_sent递增为 1(对应 tracer.h 中定义的 OpenTelemetry tracer 统计项)。

六、适用场景与注意事项

  • 默认开启:出于可观测性最佳实践,默认会在 trace 中写入envoy与版本号,便于后端按检测库版本归因与分析;
  • 何时关闭:当后端存储对字段有严格要求、或希望压缩 trace 元数据体积时,可显式设置set_instrumentation_scope: false;但需注意关闭后将丢失 span 来源库与版本的语义信息;
  • 版本联动:开启时写入的版本值来自编译进二进制的Envoy::VersionInfo::version(),随 Envoy 版本升级自动更新,无需额外配置;
  • 开关粒度:该配置仅控制 scope 层的名称与版本,若需控制telemetry.sdk.*资源属性或service.name,应分别使用同消息中的set_telemetry_sdk_resource_attributesset_service_name_resource_attribute字段(opentelemetry.proto)。

参考文件索引

  • 变更记录:changelogs/current/new_features/tracing__opentelemetry_set_instrumentation_scope.rst
  • API 定义:api/envoy/config/trace/v3/opentelemetry.proto
  • 实现代码:source/extensions/tracers/opentelemetry/tracer.cc、source/extensions/tracers/opentelemetry/opentelemetry_tracer_impl.cc、source/extensions/tracers/opentelemetry/tracer.h
  • 测试用例:test/extensions/tracers/opentelemetry/opentelemetry_tracer_impl_test.cc

【免费下载链接】envoyCloud-native high-performance edge/middle/service proxy项目地址: https://gitcode.com/GitHub_Trending/en/envoy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询