2 Export编写指南

详细内容可查看官方文档arrow-up-right

注意:以下代码均非源码。只是为了理解的简化代码。

1 整体结构

首先,Collector是核心类,有一个collect方法,用于返回指标及其样本。CollectorRegistry用来注册Collector,当有数据请求时,Registry会回调所有已注册的Collector的collect方法。用户常用的接口是Counter、Gauge、Summary和Histogram这些指标类型,它们本身也是Collector,覆盖大部分用例。高级场景可能需要自定义Collector,比如桥接其他监控系统。

  1. ​回调机制​​:

  • 所有指标数据通过 Collect() 方法回调获取

  • 注册中心在 Scrape() 时遍历调用所有收集器的 Collect()

  • 避免主动轮询,实现按需获取最新数据

  1. ​线程安全​​:

  • 注册中心使用 sync.RWMutex 保护收集器集合

  • 计数器使用 atomic 包保证原子操作

  • 自定义收集器使用 sync.Mutex 保护内部状态

  1. ​扩展性​​:

  • 通过 Collector 接口支持自定义指标类型

  • 可以创建多个 CollectorRegistry 实现不同数据隔离

  • 桥接器模式支持不同输出格式

  1. ​标准指标实现​​:

  • Counter/Gauge/Summary/Histogram 只需实现 Collector 接口

  • 提供原子操作的增减方法

  • 内置标签(label)支持实现多维度量

  1. ​注册中心职责​​:

  • 管理 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

  1. ​严格单调递增​​:值只能增加或重置为0,不允许减少

  2. ​必须包含方法​​:

    • Inc() 增加1

    • Inc(v) 按给定值增加(需校验 v ≥ 0)(go 客户端为Add)

  3. ​推荐功能​​:统计代码块中的异常数量(如Python的count_exceptions

  4. ​初始值​​:必须从0开始

2.2 Gauge

  1. ​基础功能​

    • ​可增减数值​​:表示瞬时值(如内存使用量、并发请求数)

    • ​必须方法​​:

      • Inc():+1

      • Inc(v):+任意值(支持浮点)

      • Dec():-1

      • Dec(v):-任意值(支持浮点)

      • Set(v):直接设值(允许任意数值)

    • ​初始值​​:默认从0开始,可扩展支持自定义初始值

  2. ​推荐功能​

    • SetToCurrentTime():设为当前UNIX时间戳(秒级)

    • ​跟踪进行中请求​​:自动增减计数器(如Python的track_inprogress

    • ​测量代码耗时​​:记录代码块执行时长(秒级精度)

  3. ​设计约束​

    • 接口需与Histogram/Summary的计时模式兼容(但用Set代替Observe

    • 线程安全(多协程并发安全)

2.3 Summary

​Summary​​ 用于统计观察值(如请求耗时)的分布特征,提供以下核心数据:

  • ​滑动窗口统计​​:实时计算分位数(Quantile)、总数(_sum)、样本数(_count)

  • ​不可聚合性​​:分位数无法跨实例聚合,适用于单实例性能分析

​强制要求​

  1. ​标签限制​​:

    • 禁止使用 quantile 作为用户自定义标签(内部保留用于分位数标识)

  2. ​默认行为​​:

    • ​必须​​ 默认只暴露 _count(总样本数)和 _sum(总和)

    • 分位数计算需​​显式启用​​(因计算开销大)

  3. ​必须方法​​:

  4. ​初始值​​:

    • _count_sum 必须从0开始

2.4 Histogram

Histogram​​ 用于统计可聚合的事件分布(如请求延迟),通过预定义桶(Bucket)统计样本分布,提供:

  • 各桶的样本计数(_bucket{le="x"}

  • 样本总数(_count

  • 样本总和(_sum

​强制要求​

  1. ​标签限制​

    • 禁止用户使用 le 标签(内部保留用于桶边界)

  2. ​桶配置​

    • ​必须​​ 支持手动设置桶

    • ​推荐​​ 提供线性/指数桶生成方法

    • 必须包含 +Inf 桶(自动添加)

  3. ​方法要求​

    • Observe(v float64):记录观察值(单位:秒)

    • ​推荐​​ 提供计时器接口(如 Timer()

  4. ​初始值​

    • 所有计数器(_count_sum、各桶)必须从0开始

  5. ​不可变性​

    • 桶配置创建后不可修改

2.5 指标规范

1. 指标命名规则​

  • ​格式要求​​: 必须符合 [namespace]_[subsystem]_name 格式,其中 name 为必填,其他可选。 合法示例:http_requests_totalnode_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 Pushgatewayarrow-up-right 允许将时间序列从短期服务级别批处理作业arrow-up-right推送到 Prometheus 可以抓取的中间作业。结合 Prometheus 基于文本的简单公开格式,这使得在没有客户端库的情况下,甚至可以轻松插桩 shell 脚本。

有关从 Go 中使用的信息,请参阅 Pusharrow-up-rightAddarrow-up-right 方法。

4 配置规范

1. 导出器设计原则​

  • ​开箱即用​​: 默认导出所有核心指标,无需用户额外配置,仅需指定监控目标地址。

  • ​灵活过滤​​: 提供指标过滤功能,允许按需禁用高开销或细粒度指标(如 HAProxy 的每服务器统计)。

  • ​性能优化​​: 高成本指标默认关闭,用户可手动开启(如大集群中的详细资源跟踪)。

2. 配置最佳实践​

  • ​零配置优先​​: 默认提供完整监控覆盖,降低用户启动门槛。

  • ​示例配置库​​: 为复杂场景提供预置配置模板(如 Kafka 主题监控、JVM 线程分析)。

  • ​渐进式引导​​: 通过注释说明配置项作用,帮助用户理解高级功能

3. 标准化配置格式​

  • ​强制使用 YAML​​: 所有配置文件必须采用 YAML 格式,保持生态统一性。

最后更新于