3. 指标采集基础:Counter、Histogram、Gauge、UpDownCounter 的定义与使用场景
在 OpenTelemetry 指标体系中,Instrument(测量工具) 是数据采集的最小单元。不同的 Instrument 对应不同的语义模型,选错 Instrument 会导致监控数据失真或无法正确聚合。本章深入剖析四种核心 Instrument 的定义、行为特征与典型场景。
3.1 四种核心 Instrument 概览
| Instrument | 单调性 | 聚合方式 | 典型用途 |
|---|---|---|---|
| Counter | 单调递增(只增不减) | Sum / Rate | 请求总数、错误计数、写入行数 |
| UpDownCounter | 可增可减 | Sum | 活跃连接数、队列深度、库存量 |
| Histogram | 无单调性约束 | 分位数 / 桶计数 / Sum | 请求延迟、响应大小、批处理耗时 |
| Gauge | 无单调性约束 | LastValue / Min / Max | CPU 使用率、内存占用、磁盘温度 |
选型口诀: 只增不减用 Counter,可增可减用 UpDownCounter,分布统计用 Histogram,瞬时快照用 Gauge。
3.2 Counter —— 单调递增计数器
定义: Counter 只允许 Add(positive) 操作,值永远单调递增。服务重启后归零重新计数。
核心行为:
- 只能增加,不能减少,不能重置(除非进程重启)。
- 后端自动聚合为
Sum或Rate(每秒增量)。 - 适合统计“发生了多少次”的事件。
使用场景:
- HTTP 请求总数
- 数据库查询执行次数
- 任务调度触发次数
- 错误日志产生条数
// Go 示例:记录数据库查询次数
dbQueryCounter, _ := meter.Int64Counter(
"db.queries.total",
metric.WithDescription("Total number of database queries executed"),
)
dbQueryCounter.Add(ctx, 1, metric.WithAttributes(
attribute.String("db.system", "postgresql"),
attribute.String("db.operation", "SELECT"),
))
3.3 UpDownCounter —— 可增减计数器
定义: UpDownCounter 允许 Add(positive) 和 Add(negative),值可以在正负方向变化,但不会低于零(业务层可自行约束)。
核心行为:
- 支持正负增量,后端聚合为
Sum。 - 适合跟踪“当前存量”或“瞬时水位”。
- 与 Gauge 的区别:UpDownCounter 强调累计变化量,Gauge 强调瞬时快照。
使用场景:
- 数据库连接池活跃连接数
- 消息队列待处理消息数
- 任务调度器排队任务数
- 内存池已分配块数
// Java 示例:跟踪连接池活跃连接
UpDownCounter activeConnections = meter
.upDownCounterBuilder("db.connections.active")
.setDescription("Current number of active database connections")
.build();
// 建立连接时 +1
activeConnections.add(1);
// 释放连接时 -1
activeConnections.add(-1);
常见误区: 不要用 Counter 记录连接数。连接数会下降,Counter 无法表达下降语义。此时必须使用 UpDownCounter 或 Gauge。
3.4 Histogram —— 分布直方图
定义: Histogram 将观测值分配到预定义的桶(Bucket)中,记录每个桶的计数、所有值的总和以及观测次数。不保留原始数据点。
核心行为:
- 必须指定桶边界(如 [0, 10, 50, 100, 500])。
- 输出三个聚合指标:
桶计数、总和、观测次数。 - 后端可计算
p50、p90、p99等分位数。
使用场景:
- API 响应延迟分布
- 数据库查询耗时分布
- 批处理任务处理时间分布
- 数据迁移单条记录处理耗时
# Python 示例:记录查询延迟分布
histogram = meter.create_histogram(
name="db.query.duration",
description="Histogram of database query duration in milliseconds",
unit="ms",
boundaries=[1, 5, 10, 25, 50, 100, 500, 1000],
)
histogram.record(42.5, {"db.operation": "INSERT"})
3.5 Gauge —— 瞬时快照
定义: Gauge 记录某个时间点的瞬时值,不关心历史变化趋势。通常由外部系统回调设置。
核心行为:
- 使用
Set(value)或Record(value)更新当前值。 - 后端聚合为
LastValue,也可配置Min/Max。 - 不累积,不计算速率。
使用场景:
- 当前 CPU 使用率
- 当前内存占用字节数
- 磁盘剩余空间百分比
- 数据库连接池最大连接数配置
// C# 示例:记录当前内存使用量
var memoryGauge = meter.CreateObservableGauge(
"process.memory.usage",
() => new[] { new Measurement<long>(Process.GetCurrentProcess().WorkingSet64) }
);
3.6 Instrument 选型决策流程
决策树:
- 数据是否只增不减? → 是 → Counter
- 数据是否可增可减且需要累计总量? → 是 → UpDownCounter
- 是否需要分析分布特征(p50/p99)? → 是 → Histogram
- 以上都不符合,只需当前瞬时值? → Gauge
3.7 数据库迁移场景中的 Instrument 映射
在数据库迁移任务调度场景中,不同阶段需要不同的 Instrument 来精确刻画系统状态:
| 监控指标 | 推荐 Instrument | 说明 |
|---|---|---|
| 迁移任务调度次数 | Counter | 每次调度触发 +1,只增不减 |
| 迁移失败次数 | Counter | 失败事件累积计数 |
| 当前排队任务数 | UpDownCounter | 任务入队 +1,出队 -1 |
| 单条记录迁移耗时 | Histogram | 分析 p50/p99 迁移延迟 |
| 源数据库 CPU 使用率 | Gauge | 瞬时快照,不累积 |
| 目标数据库连接池活跃数 | UpDownCounter | 连接建立/释放动态变化 |
最佳实践: 在数据库迁移任务中,优先使用 Histogram 记录迁移延迟,配合 Counter 记录总行数和失败行数,再使用 UpDownCounter 跟踪队列水位。三种 Instrument 组合即可覆盖 90% 的监控需求。