协议规范

简要概述

OpenTelemetry是由两个重要的开源观测性项目合并而成

  1. OpenTracing - 由Ben Sigelman(LightStep CEO)等人发起

    • 专注于分布式追踪标准化
    • 提供厂商中立的追踪API
  2. OpenCensus - 由Google开发并开源

    • 提供指标(Metrics)和追踪(Tracing)的采集和导出
    • 内置多种后端导出器

2019年5月,这两个项目正式合并为OpenTelemetry,由CNCF(云原生计算基金会)托管。

OpenTelemetry 指标协议被设计为传输指标数据的标准规范。为明确数据的预期用途及相关语义,指标数据流类型将融入一个双层框架:

1. 高层模型(API 层)

  • 聚焦开发者的使用体验
  • 处理离散的原始测量值(如计数器递增、测量记录)
  • 对应 OpenTelemetry SDK 的 Metrics API
  • 示例:在代码中调用 counter.Add(1)recorder.Record(25.5)

2. 底层模型(导出层)

  • 定义标准化时间序列格式
  • 处理聚合后的输出值(如总和、平均值、分位数)
  • 对应 OTLP 导出协议格式
  • 示例:生成如 http_requests_total{status="200"} 1534 的时间序列

该模型专为实现现有系统的数据导入与导出而设计,现有主流指标数据格式均可无损转换为该指标数据模型,确保语义完整性与数据保真度,其中针对 Prometheus 和 Statsd 输出格式的转换规范已作出明确定义。

数据流程

OpenTelemetry 协议(OTLP)规范定义了遥测数据在数据源、中间节点(如收集器)与后端系统之间的编码方式、传输机制及投递流程,大致流程如下:

flowchart TD A[Instrumented Application
数据源] --> B[Exporter
OTLP Exporter] B --> C{传输方式选择} C -->|HTTP| D[HTTP/1.1 or HTTP/2
Application Content Headers] C -->|gRPC| E[gRPC
gRPC Metadata Headers] D --> F{序列化格式选择} E --> F F -->|Protocol Buffers| G[编码: Protocol Buffers
二进制格式] F -->|JSON| H[编码: JSON
文本格式 可读性好] G --> I[Collector
OTLP Receiver] H --> I subgraph I [OpenTelemetry 收集器核心处理] direction LR I1[Receiver] --> I2[Processor
过滤/转换/批处理] --> I3[Exporter
格式转换与转发] end I --> J{后端系统投递} J -->|OTLP| K[后端系统 1
支持OTLP的后端] J -->|Prometheus| L[后端系统 2
Prometheus] J -->|Jaeger| M[后端系统 3
Jaeger] J -->|Zipkin| N[后端系统 4
Zipkin] J -->|Kafka| O[后端系统 5
消息队列/数据湖]

服务定义

指标(Metrics)

metrics_service.proto

service MetricsService {
  rpc Export(ExportMetricsServiceRequest) returns (ExportMetricsServiceResponse) {}
}

message ExportMetricsServiceRequest {
  repeated opentelemetry.proto.metrics.v1.ResourceMetrics resource_metrics = 1;
}

message ExportMetricsServiceResponse {
  ExportMetricsPartialSuccess partial_success = 1;
}

message ExportMetricsPartialSuccess {
  int64 rejected_data_points = 1;

  string error_message = 2;
}

日志(Logging)

logs_service.proto

service LogsService {
  rpc Export(ExportLogsServiceRequest) returns (ExportLogsServiceResponse) {}
}

message ExportLogsServiceRequest {
  repeated opentelemetry.proto.logs.v1.ResourceLogs resource_logs = 1;
}

message ExportLogsServiceResponse {
  ExportLogsPartialSuccess partial_success = 1;
}

message ExportLogsPartialSuccess {
  string error_message = 2;
}

追踪(Tracing)

trace_service.proto

service TraceService {
  rpc Export(ExportTraceServiceRequest) returns (ExportTraceServiceResponse) {}
}

message ExportTraceServiceRequest {
  repeated opentelemetry.proto.trace.v1.ResourceSpans resource_spans = 1;
}

message ExportTraceServiceResponse {
  ExportTracePartialSuccess partial_success = 1;
}

message ExportTracePartialSuccess {
  string error_message = 2;
}

OTLP/gRPC

客户端请求

默认服务端在 tcp 4317 端口监听,通过 grpc 协议对外。在建立连接后客户端可持续推送遥测数据至服务端。

客户端与服务端之间支持以下模式:

  1. 顺序传输模式(请求-响应-请求-响应)

也就是客户端上报数据,服务端成功接收后继续下次上报,一般在低延迟网络下使用比较简单。

  1. 高吞吐量传输

客户端持续上报数据而无需登录服务端响应成功。

理论公式:最大吞吐量 = (最大并发请求数 × 单请求最大容量) / (网络延迟 + 服务端响应时间)

示例分析(基于给定参数):

  • 单请求上限:100 spans
  • 网络往返延迟:200ms
  • 服务端处理时间:300ms
  • 单并发吞吐量:100 spans / (0.2s+0.3s) = 200 spans/秒

服务端响应

TODO;

OTLP/HTTP

请求体编码

  • protobuf 编码
Content-Type: application/x-protobuf
  • json 编码
Content-Type: application/json

客户端请求

默认服务端在 tcp 4318 端口监听,服务是通过 grpc-gateway 对以上 grpc 做 http 转换实现,默认几个接口定义如下:

logs_service_http.yaml

type: google.api.Service
config_version: 3
http:
 rules:
 - selector: opentelemetry.proto.collector.logs.v1.LogsService.Export
   post: /v1/logs
   body: "*"

metrics_service_http.yaml

type: google.api.Service
config_version: 3
http:
 rules:
 - selector: opentelemetry.proto.collector.metrics.v1.MetricsService.Export
   post: /v1/metrics
   body: "*"

trace_service_http.yaml

type: google.api.Service
config_version: 3
http:
 rules:
 - selector: opentelemetry.proto.collector.trace.v1.TraceService.Export
   post: /v1/traces
   body: "*"

服务端响应

TODO;