Prometheus指标类型 #
一、指标类型概述 #
1.1 四种指标类型 #
text
Prometheus指标类型:
┌─────────────────────────────────────────────┐
│ 1. Counter(计数器) │
│ • 只增不减的累积值 │
│ • 用于计数场景 │
│ • 示例:请求数、错误数 │
├─────────────────────────────────────────────┤
│ 2. Gauge(仪表盘) │
│ • 可增可减的瞬时值 │
│ • 用于当前状态 │
│ • 示例:温度、内存使用 │
├─────────────────────────────────────────────┤
│ 3. Histogram(直方图) │
│ • 观测值的分布统计 │
│ • 自动计算分位数 │
│ • 示例:请求延迟分布 │
├─────────────────────────────────────────────┤
│ 4. Summary(摘要) │
│ • 观测值的分位数统计 │
│ • 客户端计算分位数 │
│ • 示例:请求延迟分位数 │
└─────────────────────────────────────────────┘
1.2 类型选择指南 #
text
指标类型选择:
需要记录什么?
│
├── 累积数量(只增不减)
│ └── 使用 Counter
│ 示例:请求总数、错误总数
│
├── 当前状态(可增可减)
│ └── 使用 Gauge
│ 示例:温度、内存使用、队列长度
│
├── 分布情况(需要分位数)
│ │
│ ├── 可以接受近似值
│ │ └── 使用 Histogram
│ │ 优点:可聚合、可配置桶
│ │
│ └── 需要精确分位数
│ └── 使用 Summary
│ 优点:精确分位数
│ 缺点:不可聚合
二、Counter(计数器) #
2.1 概念说明 #
text
Counter特性:
┌─────────────────────────────────────────────┐
│ 定义 │
├─────────────────────────────────────────────┤
│ • 只能增加,不能减少(重启归零) │
│ • 用于记录累积值 │
│ • 通常配合rate()使用 │
└─────────────────────────────────────────────┘
时间线示例:
值
│
│ ┌───── 1000
│ ┌────┘
│ ┌────┘
│ ┌────┘
│ ┌────┘
│ ┌────┘
│ ────┘
└─────────────────────────────────> 时间
0 1 2 3 4 5
Counter只增不减,表示累积的总量
2.2 使用场景 #
text
Counter适用场景:
┌─────────────────────────────────────────────┐
│ 1. 请求计数 │
│ http_requests_total │
│ • 记录HTTP请求总数 │
│ • 配合rate计算QPS │
├─────────────────────────────────────────────┤
│ 2. 错误计数 │
│ http_errors_total │
│ • 记录错误总数 │
│ • 计算错误率 │
├─────────────────────────────────────────────┤
│ 3. 任务完成数 │
│ tasks_completed_total │
│ • 记录完成任务数 │
│ • 计算完成速率 │
├─────────────────────────────────────────────┤
│ 4. 数据处理量 │
│ bytes_processed_total │
│ • 记录处理字节数 │
│ • 计算吞吐量 │
└─────────────────────────────────────────────┘
2.3 常用查询 #
promql
# 计算每秒请求数(QPS)
rate(http_requests_total[5m])
# 计算每分钟请求数
increase(http_requests_total[1m])
# 按状态码分组计算QPS
sum by (status) (rate(http_requests_total[5m]))
# 计算错误率
sum(rate(http_errors_total[5m])) / sum(rate(http_requests_total[5m]))
# 按服务分组计算QPS
sum by (service) (rate(http_requests_total[5m]))
# 计算过去1小时的总请求数
increase(http_requests_total[1h])
2.4 代码示例 #
python
# Python客户端示例
from prometheus_client import Counter
# 创建Counter
http_requests_total = Counter(
'http_requests_total',
'Total HTTP requests',
['method', 'endpoint', 'status']
)
# 增加计数
http_requests_total.labels(method='GET', endpoint='/api/users', status='200').inc()
http_requests_total.labels(method='POST', endpoint='/api/users', status='201').inc()
# 增加指定值
http_requests_total.labels(method='GET', endpoint='/api/users', status='200').inc(5)
go
// Go客户端示例
package main
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
httpRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total HTTP requests",
},
[]string{"method", "endpoint", "status"},
)
)
func main() {
// 增加计数
httpRequestsTotal.WithLabelValues("GET", "/api/users", "200").Inc()
httpRequestsTotal.WithLabelValues("POST", "/api/users", "201").Inc()
// 增加指定值
httpRequestsTotal.WithLabelValues("GET", "/api/users", "200").Add(5)
}
三、Gauge(仪表盘) #
3.1 概念说明 #
text
Gauge特性:
┌─────────────────────────────────────────────┐
│ 定义 │
├─────────────────────────────────────────────┤
│ • 可增可减的瞬时值 │
│ • 用于记录当前状态 │
│ • 直接使用,无需rate() │
└─────────────────────────────────────────────┘
时间线示例:
值
│ ┌─────┐
│ │ │ ┌───┐
│ ────┘ └─────┘ └────
│
└─────────────────────────────────> 时间
0 1 2 3 4 5
Gauge可增可减,表示当前状态
3.2 使用场景 #
text
Gauge适用场景:
┌─────────────────────────────────────────────┐
│ 1. 系统资源 │
│ node_memory_MemAvailable_bytes │
│ • 当前可用内存 │
│ node_cpu_seconds_total │
│ • CPU使用时间 │
├─────────────────────────────────────────────┤
│ 2. 应用状态 │
│ process_open_fds │
│ • 打开的文件描述符 │
│ process_resident_memory_bytes │
│ • 进程内存使用 │
├─────────────────────────────────────────────┤
│ 3. 业务指标 │
│ queue_length │
│ • 队列长度 │
│ active_connections │
│ • 活跃连接数 │
├─────────────────────────────────────────────┤
│ 4. 环境数据 │
│ room_temperature_celsius │
│ • 室内温度 │
│ humidity_percent │
│ • 湿度百分比 │
└─────────────────────────────────────────────┘
3.3 常用查询 #
promql
# 直接查询当前值
node_memory_MemAvailable_bytes
# 计算使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 最大值
max(node_memory_MemAvailable_bytes)
# 最小值
min(node_memory_MemAvailable_bytes)
# 平均值
avg(node_memory_MemAvailable_bytes)
# 求和
sum(node_memory_MemAvailable_bytes)
# 变化量
delta(node_memory_MemAvailable_bytes[1h])
# 变化率
deriv(node_memory_MemAvailable_bytes[1h])
# 预测未来值(线性回归)
predict_linear(node_memory_MemAvailable_bytes[1h], 3600)
3.4 代码示例 #
python
# Python客户端示例
from prometheus_client import Gauge
# 创建Gauge
queue_length = Gauge(
'queue_length',
'Current queue length',
['queue_name']
)
temperature = Gauge(
'room_temperature_celsius',
'Current room temperature'
)
# 设置值
queue_length.labels(queue_name='email').set(100)
temperature.set(25.5)
# 增加值
queue_length.labels(queue_name='email').inc()
# 减少值
queue_length.labels(queue_name='email').dec()
# 增加指定值
queue_length.labels(queue_name='email').inc(10)
# 减少指定值
queue_length.labels(queue_name='email').dec(5)
go
// Go客户端示例
package main
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
queueLength = promauto.NewGaugeVec(
prometheus.GaugeOpts{
Name: "queue_length",
Help: "Current queue length",
},
[]string{"queue_name"},
)
temperature = promauto.NewGauge(prometheus.GaugeOpts{
Name: "room_temperature_celsius",
Help: "Current room temperature",
})
)
func main() {
// 设置值
queueLength.WithLabelValues("email").Set(100)
temperature.Set(25.5)
// 增加值
queueLength.WithLabelValues("email").Inc()
// 减少值
queueLength.WithLabelValues("email").Dec()
// 增加指定值
queueLength.WithLabelValues("email").Add(10)
// 减少指定值
queueLength.WithLabelValues("email").Sub(5)
}
四、Histogram(直方图) #
4.1 概念说明 #
text
Histogram特性:
┌─────────────────────────────────────────────┐
│ 定义 │
├─────────────────────────────────────────────┤
│ • 对观测值进行采样并统计分布 │
│ • 自动生成多个时间序列 │
│ • 服务端计算分位数 │
│ • 可聚合 │
└─────────────────────────────────────────────┘
生成的时间序列:
http_request_duration_seconds
├── http_request_duration_seconds_bucket{le="0.1"} # ≤0.1秒的请求数
├── http_request_duration_seconds_bucket{le="0.5"} # ≤0.5秒的请求数
├── http_request_duration_seconds_bucket{le="1.0"} # ≤1.0秒的请求数
├── http_request_duration_seconds_bucket{le="+Inf"} # 所有请求数
├── http_request_duration_seconds_sum # 总时间
└── http_request_duration_seconds_count # 总请求数
桶(Bucket)结构:
请求延迟分布:
┌─────────────────────────────────────────────┐
│ 桶边界 │ 计数 │ 累积计数 │
├─────────────────────────────────────────────┤
│ ≤0.1s │ 100 │ 100 │
│ ≤0.5s │ 200 │ 300 │
│ ≤1.0s │ 150 │ 450 │
│ ≤2.0s │ 100 │ 550 │
│ +Inf │ 50 │ 600 │
└─────────────────────────────────────────────┘
4.2 使用场景 #
text
Histogram适用场景:
┌─────────────────────────────────────────────┐
│ 1. 请求延迟 │
│ http_request_duration_seconds │
│ • 记录请求响应时间 │
│ • 计算P50、P90、P99延迟 │
├─────────────────────────────────────────────┤
│ 2. 响应大小 │
│ http_response_size_bytes │
│ • 记录响应数据大小 │
│ • 分析响应大小分布 │
├─────────────────────────────────────────────┤
│ 3. 处理时间 │
│ task_processing_duration_seconds │
│ • 记录任务处理时间 │
│ • 分析处理时间分布 │
├─────────────────────────────────────────────┤
│ 4. 批量大小 │
│ batch_size │
│ • 记录批量处理大小 │
│ • 分析批量大小分布 │
└─────────────────────────────────────────────┘
4.3 常用查询 #
promql
# 计算P50延迟(50%分位数)
histogram_quantile(0.5, rate(http_request_duration_seconds_bucket[5m]))
# 计算P90延迟(90%分位数)
histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[5m]))
# 计算P99延迟(99%分位数)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
# 按服务分组计算P99延迟
histogram_quantile(0.99, sum by (le, service) (rate(http_request_duration_seconds_bucket[5m])))
# 计算平均延迟
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])
# 计算请求速率
rate(http_request_duration_seconds_count[5m])
# 计算延迟分布(各桶占比)
sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
4.4 代码示例 #
python
# Python客户端示例
from prometheus_client import Histogram
# 创建Histogram
http_request_duration = Histogram(
'http_request_duration_seconds',
'HTTP request duration in seconds',
['method', 'endpoint'],
buckets=(0.1, 0.5, 1.0, 2.0, 5.0, 10.0, float('inf'))
)
# 记录观测值
with http_request_duration.labels(method='GET', endpoint='/api/users').time():
# 处理请求
pass
# 手动记录
http_request_duration.labels(method='GET', endpoint='/api/users').observe(0.25)
go
// Go客户端示例
package main
import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
httpRequestDuration = promauto.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration in seconds",
Buckets: []float64{0.1, 0.5, 1.0, 2.0, 5.0, 10.0},
},
[]string{"method", "endpoint"},
)
)
func main() {
// 使用Timer
timer := prometheus.NewTimer(httpRequestDuration.WithLabelValues("GET", "/api/users"))
// 处理请求
timer.ObserveDuration()
// 手动记录
httpRequestDuration.WithLabelValues("GET", "/api/users").Observe(0.25)
// 使用time.Since
start := time.Now()
// 处理请求
duration := time.Since(start).Seconds()
httpRequestDuration.WithLabelValues("GET", "/api/users").Observe(duration)
}
五、Summary(摘要) #
5.1 概念说明 #
text
Summary特性:
┌─────────────────────────────────────────────┐
│ 定义 │
├─────────────────────────────────────────────┤
│ • 对观测值进行采样并计算分位数 │
│ • 客户端计算分位数 │
│ • 分位数精确 │
│ • 不可聚合 │
└─────────────────────────────────────────────┘
生成的时间序列:
http_request_duration_seconds
├── http_request_duration_seconds{quantile="0.5"} # P50
├── http_request_duration_seconds{quantile="0.9"} # P90
├── http_request_duration_seconds{quantile="0.99"} # P99
├── http_request_duration_seconds_sum # 总时间
└── http_request_duration_seconds_count # 总请求数
Histogram vs Summary:
┌──────────────────┬─────────────────┬─────────────────┐
│ 特性 │ Histogram │ Summary │
├──────────────────┼─────────────────┼─────────────────┤
│ 分位数计算 │ 服务端 │ 客户端 │
│ 分位数精确度 │ 近似 │ 精确 │
│ 可聚合性 │ 可 │ 不可 │
│ 可配置分位数 │ 是 │ 是 │
│ 存储成本 │ 较高 │ 较低 │
│ 推荐使用 │ 推荐 │ 特殊场景 │
└──────────────────┴─────────────────┴─────────────────┘
5.2 使用场景 #
text
Summary适用场景:
┌─────────────────────────────────────────────┐
│ 适合使用Summary: │
├─────────────────────────────────────────────┤
│ • 需要精确分位数 │
│ • 不需要聚合多个实例 │
│ • 分位数配置在客户端确定 │
│ • 延迟敏感的场景 │
└─────────────────────────────────────────────┘
不推荐使用Summary:
• 需要聚合多个实例的分位数
• 需要在查询时动态计算分位数
• 需要灵活配置分位数
5.3 常用查询 #
promql
# 查询P50延迟
http_request_duration_seconds{quantile="0.5"}
# 查询P90延迟
http_request_duration_seconds{quantile="0.9"}
# 查询P99延迟
http_request_duration_seconds{quantile="0.99"}
# 计算平均延迟
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])
# 计算请求速率
rate(http_request_duration_seconds_count[5m])
# 注意:Summary不能跨实例聚合分位数
# 以下查询是错误的:
# avg(http_request_duration_seconds{quantile="0.99"}) # 无意义
5.4 代码示例 #
python
# Python客户端示例
from prometheus_client import Summary
# 创建Summary
http_request_duration = Summary(
'http_request_duration_seconds',
'HTTP request duration in seconds',
['method', 'endpoint']
)
# 设置分位数(默认P50、P90、P99)
http_request_duration = Summary(
'http_request_duration_seconds',
'HTTP request duration in seconds',
['method', 'endpoint'],
invariants=[0.5, 0.9, 0.99]
)
# 记录观测值
with http_request_duration.labels(method='GET', endpoint='/api/users').time():
# 处理请求
pass
# 手动记录
http_request_duration.labels(method='GET', endpoint='/api/users').observe(0.25)
go
// Go客户端示例
package main
import (
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
var (
httpRequestDuration = promauto.NewSummaryVec(
prometheus.SummaryOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration in seconds",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
},
[]string{"method", "endpoint"},
)
)
func main() {
// 使用Timer
timer := prometheus.NewTimer(httpRequestDuration.WithLabelValues("GET", "/api/users"))
// 处理请求
timer.ObserveDuration()
// 手动记录
httpRequestDuration.WithLabelValues("GET", "/api/users").Observe(0.25)
}
六、指标类型对比 #
6.1 对比表格 #
text
指标类型对比:
┌──────────────┬─────────────┬─────────────┬─────────────┬─────────────┐
│ 特性 │ Counter │ Gauge │ Histogram │ Summary │
├──────────────┼─────────────┼─────────────┼─────────────┼─────────────┤
│ 值类型 │ 只增 │ 可增可减 │ 观测值 │ 观测值 │
│ 主要用途 │ 累积计数 │ 当前状态 │ 分布统计 │ 分位数 │
│ 典型场景 │ 请求数 │ 内存使用 │ 延迟分布 │ 延迟分位数 │
│ 配合函数 │ rate() │ 直接使用 │ histogram_ │ 直接查询 │
│ │ increase() │ │ quantile() │ │
│ 可聚合 │ 是 │ 是 │ 是 │ 否 │
│ 存储成本 │ 低 │ 低 │ 高 │ 中 │
│ 计算成本 │ 低 │ 低 │ 服务端计算 │ 客户端计算 │
└──────────────┴─────────────┴─────────────┴─────────────┴─────────────┘
6.2 选择建议 #
text
指标类型选择建议:
1. 记录数量(只增不减)
└── 使用 Counter
• 请求数、错误数、处理量
2. 记录状态(可增可减)
└── 使用 Gauge
• 内存、CPU、队列长度、温度
3. 记录分布(需要分位数)
│
├── 多实例需要聚合
│ └── 使用 Histogram
│ • 可聚合计算分位数
│ • 服务端计算
│
└── 单实例精确分位数
└── 使用 Summary
• 客户端计算精确分位数
• 不可聚合
推荐:优先使用 Histogram
七、总结 #
指标类型要点:
| 类型 | 特点 | 使用场景 |
|---|---|---|
| Counter | 只增不减 | 请求数、错误数 |
| Gauge | 可增可减 | 内存、温度、队列长度 |
| Histogram | 分布统计 | 延迟分布、响应大小 |
| Summary | 分位数统计 | 精确分位数 |
常用查询:
| 类型 | 典型查询 |
|---|---|
| Counter | rate(metric[5m]) |
| Gauge | metric 或 avg(metric) |
| Histogram | histogram_quantile(0.99, rate(metric_bucket[5m])) |
| Summary | metric{quantile="0.99"} |
下一步,让我们学习标签与标签选择器!
最后更新:2026-03-27