用 OpenTelemetry Collector 作为统一采集入口,把日志、指标、链路三类数据一次接入炬鲸 OBSERVE。附完整配置文件、接收器/导出器选型建议与必踩的坑。
应用直连可观测平台最简单,但问题在规模。几十个服务各自把数据推给平台,每个都要配 Token、配地址、处理重试和背压;采集地址一变,所有服务都要改配置。更麻烦的是,日志、指标、链路往往来自不同的库,字段、格式、采样策略都不一致,平台收到的是要再清洗的一团乱麻。
OpenTelemetry Collector 是一个中间层:所有应用只把数据交给本地的 Collector,由 Collector 统一做处理、过滤、聚合、导出。你的应用侧只关心一件事——往 Collector 发,剩下交给它。这也意味着将来换后端、加后端,只改一个 exporter,应用一行都不用动。
先起一个 Collector,以单机 Docker 为例:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
filelog:
include: [ /var/log/app/*.log ]
start_at: end
processors:
batch:
timeout: 5s
send_batch_size: 8192
memory_limiter:
check_interval: 1s
limit_mib: 512
exporters:
otlphttp:
endpoint: https://ob.example.com/v1/traces
headers:
Authorization: "Bearer <token>"
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlphttp]
简单说明几个部分:receivers 定义数据从哪里进(otlp 收 SDK 埋点数据,filelog 收裸日志文件);processors 做加工;exporters 定义数据往哪出;service.pipelines 把它们串起来。batch 把小包并成大包、减少网络往返,memory_limiter 防止 Collector 在负载下吃光内存。
可观测数据分三种,导出地址也分开:
/v1/traces,链路追踪/v1/metrics,指标/v1/logs,日志在 service.pipelines 里为每类数据各建一条 pipeline,receiver 可以复用同一个 OTLP 端口,也可以各用各的。常见做法是一个 OTLP receiver 喂三条 pipeline,每条 pipeline 指向各自的导出地址。
应用侧接入 OpenTelemetry SDK 后,把 OTLP 的 endpoint 指向本机 Collector(localhost:4317)即可,不用再关心平台的地址和 Token——这些只在 Collector 里配一次。这才是真正的收益:接入一个新服务变成“加 SDK、设一个环境变量”,平台凭证永远不出 Collector 那台机器。
以 Java 为例,通过环境变量注入:
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
OTEL_SERVICE_NAME=order-service
memory_limiter 一定要配:高并发下 Collector 内存涨得很快,没有 limit 会 OOM,把在途数据全丢掉。limit_mib 设为主机内存的一个比例,再用 spike_limit_mib 应对突发。send_batch_size 别设太小:太小会频繁发请求,反而拖慢;8192 附近比较稳,太大又得等批次攒满、徒增延迟。Authorization: Bearer <token>,别写成 URL 参数。这个写错是“数据不上来”最常见的原因。接好后,回到炬鲸 OBSERVE 控制台,用一条查询验证三类数据是否都进来了:
SELECT source, count(*) FROM observability
WHERE ts > now() - 15m GROUP BY source
三类都在,说明接入完成。缺了哪一类,先看 Collector 配置里对应的 pipeline——receiver、processor、exporter 三者都得在 service.pipelines 里挂上,这一步最容易漏。