Vector 的 OpenTelemetry Source 接入指南:通过 gRPC/HTTP 接收 OTLP 遥测数据
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
本文是 Vector 高可观测性数据管道中opentelemetrysource 组件的完整技术指南。该组件让 Vector 能够作为 OpenTelemetry Collector 协议(OTLP)的接收端,通过 gRPC(默认端口 4317)与 HTTP(默认端口 4318)两种传输协议接收日志(logs)、指标(metrics)与链路追踪(traces)三类遥测信号,并将其转换为 Vector 原生事件或保留 OTLP 原始格式转发给下游。读完本文,你将掌握opentelemetrysource 的完整配置项、OTLP 解码行为(use_otlp_decoding)、事件字段映射细节,以及从源码层面理解其 gRPC/HTTP 双监听器的实现原理与可观测性指标。
组件概览:定位与适用场景
opentelemetrysource 是 Vector 面向可观测性数据接入的核心组件之一。它的元数据定义位于 website/cue/reference/components/sources/opentelemetry.cue,其中明确标注了该组件的关键特性:
- 交付保证:
delivery: "at_least_once"(至少一次交付),配合 source 级与端到端确认(acknowledgements)机制实现可靠投递; - 部署角色:支持
daemon(守护进程,每台机器部署一个)与aggregator(聚合器,集中汇总数据)两种形态; - 开发状态:
beta阶段,其中 metrics 与 traces 支持被标记为实验性(experimental),接口可能随版本演进调整; - 接收接口:面向 socket 的入站 TCP 监听,TLS 为可选配置(
ssl: "optional"),gRPC 与 HTTP 两个监听器均可独立启用 TLS。
从架构视角看,该 source 扮演"OTLP 摄取网关"的角色:应用通过 OpenTelemetry SDK/Collector 导出的数据可以直接落地到 Vector,再由 Vector 的路由、转换与 sink 能力分发到存储、监控或另一个 OTEL Collector。默认端口遵循 OTLP 规范约定:gRPC 为4317,HTTP 为4318。
组件使用统一标识符opentelemetry,注册于 src/sources/opentelemetry/config.rs(#[configurable_component(source("opentelemetry", ...))]),源码模块结构见 src/sources/opentelemetry/mod.rs:包含config.rs(配置定义)、grpc.rs(gRPC 服务实现)、http.rs(HTTP 服务实现)、reply.rs与status.rs(响应与状态码封装),以及tests.rs、integration_tests.rs测试文件。
最小可用配置
opentelemetrysource 的grpc与http两个配置块均为必填项(required: true),这意味着你需要至少显式配置一个监听地址。以下是最小配置示例,同时启用 gRPC 与 HTTP 两个监听器:
sources: otel: type: opentelemetry grpc: address: "0.0.0.0:4317" # gRPC 监听地址,必须包含端口 http: address: "0.0.0.0:4318" # HTTP 监听地址,必须包含端口配置生成逻辑见 src/sources/opentelemetry/config.rs 的GenerateConfig实现,它生成默认配置时 gRPC 使用0.0.0.0:4317、HTTP 使用0.0.0.0:4318,与 OTLP 标准端口保持一致。使用 Vector CLI 可通过vector generate opentelemetry快速生成该组件的默认配置骨架。
该 source 输出三个命名端口(输出流),下游组件需以<component_id>.<port>形式引用:
| 输出端口 | 数据类型 | 说明 |
|---|---|---|
logs | Log | 接收到的日志事件输出流 |
traces | Trace | 接收到的 trace 事件输出流 |
metrics | Metric | 接收到的 metric 事件输出流(启用 OTLP 解码时变为 Log 类型) |
sinks: my_sink: inputs: - otel.logs - otel.traces - otel.metrics type: ...完整配置项详解
该组件的完整配置结构由 website/cue/reference/components/sources/generated/opentelemetry.cue 生成,全部配置项整理如下:
grpc:gRPC 服务配置(必填)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
address | string | 是 | — | 监听 socket 地址,必须包含端口,示例:0.0.0.0:4317、localhost:4317 |
tls | object | 否 | 无 | 入站连接 TLS 配置(TlsEnableableConfig) |
keepalive | object | 否 | 见下 | gRPC server keepalive 参数 |
grpc.keepalive的底层定义位于 src/sources/util/grpc/mod.rs 的GrpcKeepaliveConfig:
| 参数 | 类型 | 说明 |
|---|---|---|
max_connection_age_secs | integer(秒) | 连接在被服务器主动关闭前允许存在的最大时长;不设置则不按年龄关闭连接,示例值300 |
max_connection_age_grace_secs | integer(秒) | 附加在max_connection_age_secs之上的宽限期,仅在设置了max_connection_age_secs时生效,示例值30 |
gRPC keepalive 的解析与校验可参考 src/sources/opentelemetry/tests.rs 中的config_grpc_keepalive测试,其验证了 TOML 配置中max_connection_age_secs = 300、max_connection_age_grace_secs = 30可被正确解析。
http:HTTP 服务配置(必填)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
address | string | 是 | — | 监听 socket 地址,必须包含端口,示例:0.0.0.0:4318、localhost:4318 |
headers | array of string | 否 | [] | 需要放入事件的 HTTP 请求头列表,支持通配符* |
tls | object | 否 | 无 | 入站连接 TLS 配置 |
keepalive | object | 否 | 见下 | HTTP server keepalive 参数 |
http.headers支持通配匹配:指定"*"表示将所有请求头纳入事件;支持模式化匹配如"X-*"、"User-Agent"、"X-My-Custom-Header"。需要留意的是,在 legacy 日志命名空间模式下,若事件中已存在同名字段,请求头不会被覆盖写入;而 metrics 与 traces 事件的请求头始终被添加到事件元数据中。该参数在源码中经由 src/sources/opentelemetry/http.rs 的build_param_matcher与remove_duplicates处理后构建匹配器。
http.keepalive对应vector::http::KeepaliveConfig,包含tcp_keepalive(TCP 层 keepalive)、max_connection_age_secs(连接最大存活时长)与max_connection_age_jitter_factor(抖动因子,默认0.1,用于错峰关闭连接避免惊群)。
use_otlp_decoding:OTLP 解码行为(可选)
该参数控制三类信号(logs/metrics/traces)的 OTLP 解码行为,定义于 src/sources/opentelemetry/config.rs 的OtlpDecodingConfig:
- 当某个信号启用 OTLP 解码时,保留原始 OTLP 格式,数据可直接(passthrough)转发给下游 OTEL Collector,无需
remap转换; - 未启用时,信号被转换为Vector 原生事件格式(默认行为)。
支持两种写法:
# 简单布尔形式:统一控制所有信号 use_otlp_decoding: true # 所有信号保留 OTLP 格式 # use_otlp_decoding: false # 所有信号使用 Vector 原生格式(默认)# 按信号分别配置 use_otlp_decoding: logs: false # 转换为 Vector 原生格式 metrics: false # 转换为 Vector 原生格式 traces: true # 保留 OTLP 格式三个子选项的默认值均为false:
| 子选项 | 默认值 | 说明 |
|---|---|---|
logs | false | true时日志保留 OTLP 格式 |
metrics | false | true时指标保留 OTLP 格式但以日志事件形式处理 |
traces | false | true时链路保留 OTLP 格式 |
该配置在源码中通过bool_or_struct反序列化器支持"布尔或结构体"两种形态,From<bool>实现(src/sources/opentelemetry/config.rs)保证了向后兼容性:true为所有信号启用 OTLP 解码,false全部使用 Vector 原生格式。get_signal_deserializer方法(同文件 L244-L263)会按信号类型查询对应开关,启用时构造OtlpDeserializer。
重要限制:当为 metrics 启用 OTLP 解码时:
- OTLP 格式的指标会被解析为日志事件(保留 OTLP 结构);
- 该输出与 Vector 的 metric 转换器(如
aggregate)不兼容; - 事件可直接透传给下游 OTEL Collector(适合做 OTLP 中继场景)。
配置中存在混合模式(部分信号启用、部分不启用)时,source 启动会打印信息日志提示各类信号的解码方式(src/sources/opentelemetry/config.rs)。
acknowledgements(已废弃)
source 级别的acknowledgements参数已废弃,启用或禁用它对确认行为不再有任何影响;确认行为应通过全局配置(global acknowledgements)或 sink 级别设置。source 的can_acknowledge()返回true,表明其具备端到端确认能力。
log_namespace
内部隐藏选项,用于覆盖全局日志命名空间设置(Vector 命名空间或 legacy 命名空间)。
双监听器架构:gRPC 与 HTTP 的实现原理
opentelemetrysource 的核心是同时运行 gRPC 与 HTTP 两个异步服务器,二者通过futures::join组合,任一服务器失败都会终止整个 source(见 src/sources/opentelemetry/config.rs 的build_with_tls_reloaders)。两个监听器共享同一事件管道(SourceSender)与EventsReceived计数。
gRPC 服务端(tonic 实现)
gRPC 侧基于tonic框架实现三个 OTLP Collector 服务(src/sources/opentelemetry/grpc.rs):
| 服务 | gRPC 方法 | 对应输出 |
|---|---|---|
LogsServiceServer | ExportLogsServiceRequest→ExportLogsServiceResponse | logs |
MetricsServiceServer | ExportMetricsServiceRequest→ExportMetricsServiceResponse | metrics |
TraceServiceServer | ExportTraceServiceRequest→ExportTraceServiceResponse | traces |
三个服务注册到tonic::transport::server::RoutesBuilder后由run_grpc_server_with_routes启动。每个服务都通过.max_decoding_message_size(max_decompressed_size_bytes())设置了消息解码上限,与全局解压缩大小上限对齐(见 src/sources/util/decompression.rs 的DEFAULT_MAX_DECOMPRESSED_SIZE_BYTES),防止超大请求造成内存压力。gzip、zstd 等压缩协商由sources::util::grpc中的DecompressionAndMetricsLayer统一处理,因此服务实现本身不重复调用.accept_compressed(..)。
gRPC 服务在处理事件时(handle_events):若启用了 OTLP 解码,则把 protobuf 请求重新编码为字节流交给OtlpDeserializer解析(输出事件为保留 OTLP 结构的日志);否则直接调用into_event_iter转换为 Vector 原生事件。事件经send_batch_named送入指定端口管道,并通过BatchNotifier等待下游确认:Delivered返回成功响应,Errored映射为 gRPCinternal状态,Rejected映射为data_loss状态(src/sources/opentelemetry/grpc.rs)。
HTTP 服务端(warp 实现)
HTTP 侧基于warp构建路由过滤器(src/sources/opentelemetry/http.rs)。build_warp_filter将日志、指标、trace 三类过滤器合并,每条路由约束如下:
POST /v1/logs (Content-Type: application/x-protobuf) POST /v1/traces POST /v1/metrics路由构建逻辑见build_ingest_filter(src/sources/opentelemetry/http.rs),它要求:
- HTTP 方法为
POST; - 路径为
/v1/<signal>(logs / traces / metrics),与 OTLP/HTTP 规范一致; Content-Type必须精确匹配(忽略大小写)application/x-protobuf;- 支持
Content-Encoding声明的压缩体(decompress_body解压),并受capped_body的 body 大小上限约束。
请求体经 prost 反序列化为对应的Export*ServiceRequest后,与 gRPC 路径一样转换为事件流。响应方面,成功时返回 protobuf 编码的空Export*ServiceResponse;解码失败时返回Status(code=2 UNKNOWN)与 400 状态码;下游投递失败时返回 500。HTTP 服务器还支持 keepalive 连接年龄限制(MaxConnectionAgeLayer)与请求追踪层(build_http_trace_layer)。
事件转换:从 OTLP 到 Vector 原生事件
日志事件字段映射
当use_otlp_decoding.logs为false时,OTLPLogRecord被转换为 Vector 日志事件,字段结构定义于 website/cue/reference/components/sources/opentelemetry.cue,schema 声明见 src/sources/opentelemetry/config.rs 的outputs方法:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
attributes | object | 否 | 描述具体事件发生的属性,如http.status.code、http.url、自定义应用标签 |
resources | object | 否 | 描述资源的属性集,如service.name、service.version、k8s.pod.uid、container.name |
scope.name | string | 否 | 插桩作用域名称(通常为 logger 名称),示例some.module.name |
scope.version | string | 否 | 插桩作用域版本,示例1.2.3 |
scope.attributes | object | 否 | 属于插桩作用域的属性集 |
scope.dropped_attributes_count | uint | 否 | 插桩作用域被丢弃的属性数量(非零时存在) |
message | string | 否 | 日志记录主体,示例20200415T072306-0700 INFO I like donuts |
trace_id | string | 否 | W3C Trace Context 定义的请求 trace id,示例66346462623365646437363566363230 |
span_id | string | 否 | 日志所属处理 span 的 id,示例43222c2d51a7abe3 |
severity_number | uint | 否 | 严重级别数值,数值越小越不严重(debug),越大越严重(error/critical),示例 3、9、17、24 |
severity_text | string | 否 | 严重级别文本(即日志级别),示例TRACE3、INFO、ERROR、FATAL4 |
flags | uint | 否 | W3C Trace Context 规范定义的 trace flag |
timestamp | timestamp | 是 | 事件发生时间(UTC),由 protobuftime_unix_nano转换;未设置或为 0 时取observed_timestamp |
observed_timestamp | timestamp | 是 | 采集系统观察到事件的时间(UTC),由observed_time_unix_nano转换;未设置或为 0 时取当前时间 |
dropped_attributes_count | uint | 是 | 因采集限制而丢弃的属性计数 |
上述映射行为在 src/sources/opentelemetry/tests.rs 的receive_grpc_logs_vector_namespace测试中被逐字段验证:包括opentelemetry.resources、opentelemetry.attributes、opentelemetry.scope.name/version/attributes/dropped_attributes_count、opentelemetry.trace_id/span_id/severity_text/severity_number/flags/observed_timestamp/timestamp/dropped_attributes_count等元数据字段,以及source_type: "opentelemetry"与ingest_timestamp注入。legacy 命名空间下的扁平化字段布局则由receive_grpc_logs_legacy_namespace测试验证(同文件 L335-L397)。
指标类型映射
当use_otlp_decoding.metrics为false时,OTLP 指标被转换为 Vector 原生指标。由于内部数据模型存在结构性差异,指标支持属于实验性功能,映射规则如下(见 website/cue/reference/components/sources/opentelemetry.cue):
- 聚合临时性(Aggregation Temporality)决定 MetricKind:若某指标类型支持临时性,
Delta对应 Vector 的Incremental(增量),否则为Absolute(绝对值); - Gauge→ Vector
Gauge; - Sum→
is_monotonic为true时映射为 VectorCounter,为false时映射为 VectorGauge; - Histogram→ Vector
AggregatedHistogram; - Exponential Histogram→ 同样映射为 Vector
AggregatedHistogram,bucket 边界从指数刻度(scale)重建; - Summary→ Vector 聚合
Summary。
这些映射在测试中均有对应用例,例如receive_sum_metric(is_monotonic: true+ Cumulative →Counter,Absolute)、receive_sum_non_monotonic_metric(→Gauge)、receive_gauge_metric、receive_histogram_metric与receive_histogram_delta_metric(Cumulative→Absolute / Delta→Incremental)、receive_exponential_histogram_metric等(src/sources/opentelemetry/tests.rs 及后续)。指标标签(tags)由资源属性、作用域属性与数据点属性共同构成,测试中可见resource.service.name、scope.name、scope.version等标签前缀。
链路追踪(traces)
Vector 内部目前没有强类型的 trace 结构,trace 事件以类似日志的 key/value map 形式存储,因此 trace 支持属于实验性功能,未来可能演进为结构化格式。当use_otlp_decoding.traces为false时,OTLPSpan经into_event_iter转换为 Vector trace 事件,从traces端口输出。启用 OTLP 解码时,trace 保留 OTLP 结构,事件体包含resourceSpans/scopeSpans/spans层级(JSON 字段名定义见 lib/opentelemetry-proto/src/proto.rs)。
OTLP 批量事件计数
当启用 OTLP 解码时,单个事件可能包含整个 OTLP 批次(batch),为了让EventsReceived计数与其他 source 保持口径一致,src/sources/opentelemetry/mod.rs 的count_otlp_items会深入事件结构统计scopeLogs.logRecords、scopeMetrics.metrics、scopeSpans.spans中的实际条数。
实战场景一:OTLP 日志直通(Passthrough)到 OTEL Collector
使用use_otlp_decoding最典型的场景是将 OTLP 格式日志原样转发给下游 OTEL Collector,全程无需remap转换。CUE 文档(website/cue/reference/components/sources/opentelemetry.cue)给出的推荐配置如下:
sources: otel: type: opentelemetry grpc: address: "0.0.0.0:4317" http: address: "0.0.0.0:4318" use_otlp_decoding: logs: true sinks: otel_sink: inputs: - otel.logs type: opentelemetry protocol: type: http uri: http://localhost:5318/v1/logs encoding: codec: otlp同一模式同样适用于 metrics 与 traces。但需再次强调:OTLP 格式的指标无法转换为 Vector 指标格式,因此启用use_otlp_decoding.metrics后,OTLP 指标会以保留 OTLP 格式的日志事件形式呈现——这会禁止使用aggregate等 metric 转换器,但能够便捷地直通到 OTEL Collector。
实战场景二:在 Kubernetes 中以 DaemonSet/Aggregator 形态部署
由于opentelemetrysource 支持daemon与aggregator两种部署角色,推荐部署形态为:每个节点运行一个 Vector Agent(daemon 角色)作为 OTLP 入口,或部署独立的 Vector Aggregator 集中接收来自各节点/应用的 OTLP 数据。仓库中的 Helm chart 清单(distribution/kubernetes/vector-agent 与 distribution/kubernetes/vector-aggregator)提供了这两类部署的现成 YAML 清单参考。对于集群内 OTLP 上报,SDK 侧通常将 OTLP endpoint 指向聚合器的 Service 地址与 4317/4318 端口。
TLS 与安全配置
Vector 使用 OpenSSL 处理 TLS 协议(其成熟度是选型原因)。可分别通过grpc.tls.*与http.tls.*选项启用并调节 TLS 行为,或通过 OpenSSL 配置文件进行更细粒度控制。OpenSSL 配置文件默认路径为/usr/local/ssl/openssl.cnf,也可通过OPENSSL_CONF环境变量指定。TlsEnableableConfig支持enabled、crt(证书)、key(私钥)等标准字段,同时两个监听器还支持运行时热替换 TLS 接受器(TlsAcceptorReloader,见 src/sources/opentelemetry/config.rs 的build_with_tls_reloaders)。
sources: otel: type: opentelemetry grpc: address: "0.0.0.0:4317" tls: enabled: true crt: /etc/vector/tls/server.crt key: /etc/vector/tls/server.key http: address: "0.0.0.0:4318" tls: enabled: true crt: /etc/vector/tls/server.crt key: /etc/vector/tls/server.key可观测性指标
opentelemetrysource 自带内部遥测指标(见 website/cue/reference/components/sources/opentelemetry.cue),可用于监控其健康状态:
| 指标 | 说明 |
|---|---|
grpc_server_handler_duration_seconds | gRPC 服务处理器耗时分布 |
grpc_server_messages_received_total | gRPC 接收消息总数 |
grpc_server_messages_sent_total | gRPC 发送消息总数 |
http_server_handler_duration_seconds | HTTP 服务处理器耗时分布 |
http_server_requests_received_total | HTTP 接收请求总数 |
http_server_responses_sent_total | HTTP 发送响应总数 |
此外,内部事件EventsReceived(含事件数与字节数)与BytesReceived(协议为 http/https)在 src/sources/opentelemetry/http.rs 与 gRPC 的handle_events中被持续记录,可用于吞吐量监控。请求解码失败会触发HttpBadRequest内部事件。
源码速览与测试验证
若希望深入理解该组件的实现,建议按以下路径阅读:
- 配置与装配:src/sources/opentelemetry/config.rs — 配置结构体、
build_with_tls_reloaders双服务器装配、outputsschema 声明; - gRPC 服务:src/sources/opentelemetry/grpc.rs — 三个 OTLP Collector 服务的实现与确认处理;
- HTTP 服务:src/sources/opentelemetry/http.rs — warp 路由、压缩解压、事件解码与错误响应;
- 元数据与生成文档:website/cue/reference/components/sources/opentelemetry.cue 与 website/cue/reference/components/sources/generated/opentelemetry.cue;
- 单元测试:src/sources/opentelemetry/tests.rs — 覆盖 gRPC/HTTP 双协议下 logs、各类 metrics(Sum/Gauge/Histogram/Exponential Histogram/Summary)与 traces 的完整转换断言;
- 集成测试:src/sources/opentelemetry/integration_tests.rs — 需要
opentelemetry-integration-testsfeature 的真实环境验证。
总结
opentelemetrysource 是 Vector 与 OpenTelemetry 生态对接的关键入口:它以符合 OTLP 规范的 gRPC(4317)与 HTTP(4318)双协议接收 logs、metrics、traces 三类信号,既可将 OTLP 数据转换为 Vector 原生事件以接入 Vector 完整的转换与路由能力,也可通过use_otlp_decoding保留原始 OTLP 格式实现到下游 OTEL Collector 的零转换直通。对于正在构建统一可观测性管道、希望以 Vector 作为 OTLP 摄取网关的团队,理解本组件的配置语义、字段映射与双监听器实现,是正确落地这一架构的前提。
【免费下载链接】vectorA high-performance observability data pipeline.项目地址: https://gitcode.com/GitHub_Trending/vect/vector
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考