2. OpenTelemetry 指标模型基础:Counter、Histogram、Gauge、UpDownCounter 的概念与数据结构
在深入指标重命名与标签合并之前,必须牢固掌握 OpenTelemetry (OTel) 定义的四种核心指标类型。每种类型都对应特定的数据采集语义和聚合方式,错误的选择会导致监控数据失真。本节将逐一拆解其概念、适用场景及底层数据结构。
2.1 指标类型总览与选择依据
OTel 指标模型围绕“单调性”和“可加性”两个维度定义了四种基础类型。下表从核心特征出发,帮助你在实际埋点中快速决策。
| 指标类型 | 单调性 | 可加性 | 典型场景 | 聚合倾向 |
|---|---|---|---|---|
| Counter | 单调递增 | 是 | 请求总数、错误总数 | Sum / Rate |
| UpDownCounter | 可增可减 | 是 | 队列长度、活跃连接数 | Sum |
| Histogram | 不适用 | 否(分桶统计) | 请求延迟、响应大小 | 分桶计数 / 分位数 |
| Gauge | 无约束 | 否(快照值) | CPU 温度、内存使用量 | LastValue |
2.2 Counter(计数器)—— 单调递增的累积量
Counter 是最常用的指标类型,代表一个只能增加的累积值。它在系统重启或重置时归零,但生命周期内绝不允许减少。典型用例包括 HTTP 请求总数、数据库写入行数、任务执行次数。
数据结构定义
Counter 的数据点由时间戳、值(double 或 int64)和标签集合组成。其核心约束是 delta >= 0。
// OTel Protobuf 简化结构
message CounterDataPoint {
// 标签列表,用于维度拆解
repeated KeyValue attributes = 1;
// 起始时间戳(第一次采集或上次重置)
fixed64 start_time_unix_nano = 2;
// 当前采集时间戳
fixed64 time_unix_nano = 3;
// 单调递增的累积值
double value = 4;
// 可选:指数直方图桶(用于高精度聚合)
repeated Exemplar exemplars = 5;
}
2.3 UpDownCounter(上下计数器)—— 可增可减的累积量
UpDownCounter 是 Counter 的泛化版本,允许值增加或减少。它仍然是一个累积量,但 delta 可以为负数。适用于需要追踪“水位”变化的场景,如活跃请求数、待处理消息数、连接池大小。
与 Counter 的核心差异
| 特性 | Counter | UpDownCounter |
|---|---|---|
| Delta 符号 | 仅非负 | 正、负、零 |
| 聚合语义 | Sum(单调递增) | Sum(可波动) |
| 典型后端处理 | 计算速率(Rate) | 直接展示 Sum |
| 重置行为 | 归零后重新累积 | 归零后重新累积 |
2.4 Histogram(直方图)—— 分布统计的基石
Histogram 不记录单个值,而是将观测值分配到预定义的桶(Bucket)中,并记录每个桶的计数。它用于分析数据的分布特征,如 P50/P99 延迟、请求体大小分布。Histogram 是性能监控中最强大的指标类型之一。
数据结构与桶边界
message HistogramDataPoint {
repeated KeyValue attributes = 1;
fixed64 start_time_unix_nano = 2;
fixed64 time_unix_nano = 3;
// 显式桶边界(递增序列),例如 [0, 10, 50, 100, 500]
repeated double explicit_bounds = 4;
// 每个桶的计数,长度 = explicit_bounds + 1
repeated uint64 bucket_counts = 5;
// 所有观测值的总和
double sum = 6;
// 观测值总数
uint64 count = 7;
// 最小值(可选)
optional double min = 8;
// 最大值(可选)
optional double max = 9;
}
[0, 10, 50, 100] 会产生 5 个桶:(-∞, 0]、[0, 10)、[10, 50)、[50, 100)、[100, +∞)。bucket_counts[0] 对应第一个桶(小于等于 0 的值)。合理设置桶边界直接影响分位数计算的精度。
2.5 Gauge(仪表盘)—— 瞬时快照值
Gauge 代表一个可以上下波动的瞬时值,没有累积语义。每次采集都是当前状态的快照,后端通常只保留最后一个值(LastValue)。适用于 CPU 使用率、内存占用、磁盘温度等物理或系统指标。
数据结构特点
Gauge 的数据结构是所有指标类型中最简单的,因为它不需要 start_time_unix_nano,也没有桶或累积计数。
message GaugeDataPoint {
repeated KeyValue attributes = 1;
fixed64 time_unix_nano = 2;
double value = 3; // 瞬时快照值
}
2.6 四种指标的数据流与聚合关系
下图展示了从 SDK 采集到后端聚合的完整数据流,重点突出每种指标在 Collector 或后端中的默认聚合方式。
2.7 指标数据点通用属性
无论哪种指标类型,其数据点都共享一组通用属性,这些属性在重命名和标签合并操作中至关重要。
- Name(指标名称): 唯一标识,如
http.server.request_count。重命名操作直接修改此字段。 - Attributes(标签集合): 键值对列表,如
{method: GET, status: 200}。标签合并操作在此字段上进行。 - TimeUnixNano(时间戳): 采集时刻的纳秒级 Unix 时间戳。
- StartTimeUnixNano(起始时间戳): 仅 Counter、UpDownCounter、Histogram 需要,表示累积周期的起点。
- Value / BucketCounts / Sum / Count: 指标类型特定的数值载荷。