2 Export编写指南
详细内容可查看官方文档
注意:以下代码均非源码。只是为了理解的简化代码。
1 整体结构
首先,Collector是核心类,有一个collect方法,用于返回指标及其样本。CollectorRegistry用来注册Collector,当有数据请求时,Registry会回调所有已注册的Collector的collect方法。用户常用的接口是Counter、Gauge、Summary和Histogram这些指标类型,它们本身也是Collector,覆盖大部分用例。高级场景可能需要自定义Collector,比如桥接其他监控系统。
回调机制:
所有指标数据通过
Collect()方法回调获取注册中心在
Scrape()时遍历调用所有收集器的Collect()避免主动轮询,实现按需获取最新数据
线程安全:
注册中心使用
sync.RWMutex保护收集器集合计数器使用
atomic包保证原子操作自定义收集器使用
sync.Mutex保护内部状态
扩展性:
通过 Collector 接口支持自定义指标类型
可以创建多个 CollectorRegistry 实现不同数据隔离
桥接器模式支持不同输出格式
标准指标实现:
Counter/Gauge/Summary/Histogram 只需实现 Collector 接口
提供原子操作的增减方法
内置标签(label)支持实现多维度量
注册中心职责:
管理 Collector 的生命周期
提供统一的指标收集入口
保证线程安全的并发访问
2 指标
****1. 核心指标类型要求**
必须包含:Counter(计数器)和 Gauge(仪表盘) Counter用于累加计数(如请求总数),Gauge表示瞬时值(如内存使用量)。
至少包含一个高级类型:Summary(摘要)或 Histogram(直方图) Summary用于跟踪分位数(如响应时间的P99),Histogram通过预定义桶(Bucket)统计分布。
2. 文件静态变量设计
指标应作为全局变量定义在需要监控的代码文件内,与业务代码共存。
例如在
api_handler.go中直接定义HTTP请求计数器,避免将指标对象在代码中层层传递。客户端库需支持这种用法,减少用户的心智负担。
3. 默认注册中心机制
提供默认CollectorRegistry,自动收集所有标准指标。
用户创建指标时无需手动注册,默认即加入全局注册中心。
允许禁用自动注册或指定自定义注册中心,满足测试和批处理场景的隔离需求。
4. 多语言实现差异
Java/Go:适合使用Builder模式(链式调用配置参数),增强可读性和扩展性。
Python:利用关键字参数直接在构造函数中完成配置,保持简洁性。
所有语言实现需保持一致的语义,但API设计应符合语言习惯。
2.1 Counter
严格单调递增:值只能增加或重置为0,不允许减少
必须包含方法:
Inc()增加1Inc(v)按给定值增加(需校验v ≥ 0)(go 客户端为Add)
推荐功能:统计代码块中的异常数量(如Python的
count_exceptions)初始值:必须从0开始
2.2 Gauge
基础功能
可增减数值:表示瞬时值(如内存使用量、并发请求数)
必须方法:
Inc():+1Inc(v):+任意值(支持浮点)Dec():-1Dec(v):-任意值(支持浮点)Set(v):直接设值(允许任意数值)
初始值:默认从0开始,可扩展支持自定义初始值
推荐功能
SetToCurrentTime():设为当前UNIX时间戳(秒级)跟踪进行中请求:自动增减计数器(如Python的
track_inprogress)测量代码耗时:记录代码块执行时长(秒级精度)
设计约束
接口需与Histogram/Summary的计时模式兼容(但用
Set代替Observe)线程安全(多协程并发安全)
2.3 Summary
Summary 用于统计观察值(如请求耗时)的分布特征,提供以下核心数据:
滑动窗口统计:实时计算分位数(Quantile)、总数(_sum)、样本数(_count)
不可聚合性:分位数无法跨实例聚合,适用于单实例性能分析
强制要求
标签限制:
禁止使用
quantile作为用户自定义标签(内部保留用于分位数标识)
默认行为:
必须 默认只暴露
_count(总样本数)和_sum(总和)分位数计算需显式启用(因计算开销大)
必须方法:
初始值:
_count和_sum必须从0开始
2.4 Histogram
Histogram 用于统计可聚合的事件分布(如请求延迟),通过预定义桶(Bucket)统计样本分布,提供:
各桶的样本计数(
_bucket{le="x"})样本总数(
_count)样本总和(
_sum)
强制要求
标签限制
禁止用户使用
le标签(内部保留用于桶边界)
桶配置
必须 支持手动设置桶
推荐 提供线性/指数桶生成方法
必须包含
+Inf桶(自动添加)
方法要求
Observe(v float64):记录观察值(单位:秒)推荐 提供计时器接口(如
Timer())
初始值
所有计数器(
_count、_sum、各桶)必须从0开始
不可变性
桶配置创建后不可修改
2.5 指标规范
1. 指标命名规则
格式要求: 必须符合
[namespace]_[subsystem]_name格式,其中name为必填,其他可选。 合法示例:http_requests_total、node_memory_usage_bytes禁止动态名称: 避免动态生成指标名称(如
api_<method>_requests),应改用标签:api_requests_total{method="GET"}
2. 指标描述要求
强制要求: Gauge/Counter/Summary/Histogram 必须提供描述(Help 文本)。 自定义 Collector 中的指标也必须包含描述。
推荐实践: 描述应清晰说明指标用途,官方库示例需保持高质量文档。
3. 数据展示规范
输出格式: 必须支持 Prometheus 文本格式(text-based exposition format)。
顺序要求: 鼓励对指标进行稳定排序(如按字母顺序),前提是不显著影响性能。
2.5.1 指标命名规范
** 命名规范**
清晰明确:指标名称需让熟悉 Prometheus 的用户能快速理解其含义。 ✅ 正确示例:
http_incoming_requests_total(明确用途) ❌ 避免示例:requests_total(含义模糊)子系统关联:每个指标应严格对应一个子系统或文件。 ✅ 示例:
kafka_message_queue_size(Kafka 消息队列大小)前缀规范:
应用指标应添加导出器名称前缀,如
haproxy_up。保留前缀
process_和scrape_需谨慎使用,例如jmx_scrape_duration_seconds。
2. 单位与数据格式
基础单位:使用秒(
seconds)、字节(bytes)等标准单位,避免转换(如毫秒)。 ✅ 正确示例:request_duration_seconds❌ 错误示例:request_duration_millis比率与百分比:
暴露两个独立计数器而非百分比,例如:
计算失败率:
rate(http_requests_total{status="failed"}[5m]) / rate(http_requests_total[5m])
3. 命名格式
蛇形命名法(
snake_case): ✅ 示例:node_cpu_usage_seconds❌ 避免驼峰式:nodeCPUUsageSeconds合法字符:仅使用
[a-zA-Z0-9_:],冒号(:)保留给记录规则。 ✅ 正确示例:api:http_requests_total(记录规则) ❌ 错误示例:api.http.requests.total
4. 后缀与类型匹配
保留后缀:
_sum、_count、_bucket和_total后缀用于摘要、直方图和计数器。除非您要生成其中之一,否则请避免使用这些后缀。避免滥用:非上述类型的指标不得使用这些后缀。
5. 特殊场景处理
成功/失败指标:
使用独立指标而非标签:
计算失败率:
http_failed_requests_total / (http_successful_requests_total + http_failed_requests_total)
领域特定名称:
对 SNMP、网络设备等保留原名,但在帮助信息中说明。
2.6 标签
1. 标签一致性要求
同一指标标签名必须一致 同一指标(如 Counter、Gauge)的不同实例禁止使用不同标签名。例如: ✅ 合法:
http_requests_total{method="GET"},http_requests_total{method="POST"}❌ 非法:http_requests_total{method="GET"},http_requests_total{status="200"}自定义收集器标签建议 建议自定义 Collector 保持标签名一致,但客户端库不强制验证,以支持少数特殊场景。
2. API 设计原则
标签可选性 API 应支持标签但不强制使用,允许创建无标签指标:
标签名验证 客户端库必须验证标签名合法性(仅允许
[a-zA-Z0-9_]且不以数字开头)。
3. 标签操作方法
Child 模式 通过
labels()方法获取带标签的指标实例(Child):缓存优化 Child 实例应支持缓存,避免重复查找开销:
生命周期管理
remove():删除指定标签的 Child,停止导出数据。
clear():删除所有 Child,重置指标。
4. 初始化要求
无标签指标必须初始化 避免因未初始化导致指标缺失:
5. 标签策略
避免指标名称包含标签: ✅ 正确示例:
cache_operations_total+ 标签{type="hit"}❌ 错误示例:cache_hits_total(标签值不应成为指标名)高基数处理:
当单一指标标签组合过多时,拆分为多个指标(如按操作类型拆分)。
示例:
db_query_duration_seconds{operation="select"}, `db_query_duration_seconds{operation="insert"}
3 推送指标
有时,需要监控无法抓取的组件。这 Prometheus Pushgateway 允许将时间序列从短期服务级别批处理作业推送到 Prometheus 可以抓取的中间作业。结合 Prometheus 基于文本的简单公开格式,这使得在没有客户端库的情况下,甚至可以轻松插桩 shell 脚本。
有关从 Go 中使用的信息,请参阅 Push 和 Add 方法。
4 配置规范
1. 导出器设计原则
开箱即用: 默认导出所有核心指标,无需用户额外配置,仅需指定监控目标地址。
灵活过滤: 提供指标过滤功能,允许按需禁用高开销或细粒度指标(如 HAProxy 的每服务器统计)。
性能优化: 高成本指标默认关闭,用户可手动开启(如大集群中的详细资源跟踪)。
2. 配置最佳实践
零配置优先: 默认提供完整监控覆盖,降低用户启动门槛。
示例配置库: 为复杂场景提供预置配置模板(如 Kafka 主题监控、JVM 线程分析)。
渐进式引导: 通过注释说明配置项作用,帮助用户理解高级功能
3. 标准化配置格式
强制使用 YAML: 所有配置文件必须采用 YAML 格式,保持生态统一性。
最后更新于