Prometheus 监控接入规范

目录

一、目的

二、自定义监控指标定义规范

2.1 基本命名规范

2.1.1 指标命名规范

2.1.2 标签名称

2.2 控制基数

2.2.1 避免高基数标签

2.2.2 预定义标签集

2.2.3 动态数据的处理

2.2.4 评估与监控基数

2.2.5 降低历史数据的保留

2.2.6 适当使用 Histogram 和 Summary

2.2.7 示例

2.3 指标类型

2.4 标签 (Labels)

2.5 单位 (Units)

三、自定义监控指标的实现

3.1 指标注册

3.2 指标暴露

3.3 合理模块化与封装

封装指标创建

3.4 优化打点性能

缓存和批处理

延迟操作

3.5 文档与注释

注释与文档


一、目的

本规范旨在指导研发团队在开发过程中正确定义、使用和注册自定义监控指标,确保在 Prometheus 监控系统中,所有指标具备一致性、规范性和高可观测性,为系统性能优化和问题排查提供可靠的数据支持。

二、自定义监控指标定义规范

2.1 基本命名规范

2.1.1 指标命名规范

  • 前缀: 使用清晰的前缀区分不同业务领域或服务。例如:

    • http_:与 HTTP 请求相关的指标。

    • db_:与数据库相关的指标。

    • cache_:与缓存系统相关的指标。

  • 命名风格: 使用小写字母和下划线 _ 分隔词。指标名称应简单易懂,并反映其所代表的内容。

    • 示例: http_request_duration_seconds, db_query_count

  • 简洁明了: 指标名称应当简洁、描述性强,便于理解和使用。避免使用复杂、难以理解的名称。例如,http_requests_total 明确表明它代表 HTTP 请求的总数。

  • 使用标准前缀和单位: 遵循 Prometheus 社区推荐的命名惯例,以确保一致性和可读性。常见的后缀包括 _total 表示计数器,_duration_seconds 表示时间度量。确保单位明确,避免混淆。

    • 示例:

      • request_duration_seconds: 表示请求的持续时间,单位为秒。

      • disk_io_bytes_total: 表示磁盘 I/O 的总字节数。

  • 避免缩写: 除非是非常常见的缩写,否则应避免使用缩写来命名指标。例如,cpu_usage_ratio 要优于 cpu_use_rt

2.1.2 标签名称

  • 规范化名称:

    • 标签应使用小写字母,并使用下划线 _ 分隔单词。

    • 避免大小写混用或混淆的标签命名。

    • 示例:service, region, method, status_code

  • 标签值的规范性:

    • 标签值应具有实际业务意义,能够帮助区分和筛选数据。

    • 标签值尽量少变动,避免使用高基数的值如用户ID、请求ID等。

2.2 控制基数

控制基数是自定义监控指标设计中的一个关键因素,直接影响 Prometheus 的性能和存储需求。基数(cardinality)指的是某个指标的不同标签组合生成的唯一时间序列数量。过高的基数会导致 Prometheus 需要存储和处理大量的时间序列数据,从而增加存储开销、查询延迟,甚至可能导致系统性能下降或崩溃。因此,在设计自定义监控指标时,务必注意控制基数。

2.2.1 避免高基数标签
  • 标签值尽量少变动:

    • 使用固定范围的标签值,比如状态码、请求方法、主机名等。

    • 避免使用如用户 ID、请求 ID、设备 ID 等高基数标签值,因为这些标签可能会为每个独立请求创建一个新的时间序列。

  • 限制动态标签:

    • 尽量避免使用可能随每次请求而变化的标签,如 URL、查询参数或时间戳等。

    • 如果必须使用,可以考虑通过哈希或分桶的方式来降低基数。

  • 汇总与聚合:

    • 考虑将高度动态的标签进行汇总或聚合处理,例如通过 serviceregioninstance 等更高层次的标签来替代过于细粒度的标签。

2.2.2 预定义标签集
  • 限制标签组合:

    • 预先定义好合理的标签集,避免随意添加新的标签组合。这样可以有效控制时间序列的数量。

    • 示例:

      • 定义好固定的请求方法和状态码标签组合,如 method="GET"status_code="200",而不是对每个不同的 URL 都创建新的标签组合。

  • 固定标签值范围:

    • 对于某些业务场景,可以设定固定的标签值范围。例如,对于请求的响应时间可以分为 fastnormalslow 三类,而不是直接记录具体的时间值。

2.2.3 动态数据的处理
  • 减少动态数据打点:

    • 对于一些动态变化的数据,可以考虑减少其打点的频率,或者在后台通过汇总任务来定期更新指标,而不是实时更新。

  • 批量处理:

    • 对高频率产生的动态数据,可以通过批量处理的方式减少标签的变动。例如,将一分钟内的所有请求统计成一个总量,而不是单独记录每一次请求的详细信息。

2.2.4 评估与监控基数
  • 定期评估基数:

    • 定期检查 Prometheus 中指标的基数情况,识别出可能存在高基数的问题指标,并进行优化调整。

  • 监控基数变化:

    • 实时监控自定义指标的基数,及时发现和处理基数异常增长的情况,避免系统压力过大。

2.2.5 降低历史数据的保留
  • 合理设置数据保留周期:

    • 对于高基数的指标,可以考虑缩短其数据保留周期,减轻存储压力。通过配置 retention 策略,合理设置数据的保留时间。

  • 历史数据聚合:

    • 对历史数据进行聚合存储,将精细的时间序列数据汇总为更为粗粒度的时间段数据,降低历史数据的存储需求。

2.2.6 适当使用 Histogram 和 Summary
  • 选择适合的指标类型:

    • 对于需要监控的数据分布情况,优先使用 Histogram 而非 Summary,因为 Histogram 提供的桶可以有效减少标签值的动态变化。

  • 自定义桶的大小和范围:

    • 在使用 Histogram 时,自定义桶的数量和范围,以避免生成过多的时间序列。确保桶的数量和范围合理,既能满足监控需求,又不会导致基数过高。

2.2.7 示例
  • 避免高基数标签: 高基数标签会生成大量的时间序列,增加存储和检索的负担。避免使用可能产生大量唯一值的标签,例如用户ID、IP地址、请求ID等。

    • Bad: 标签 method 使用过于细化的路径,导致基数过高。

      status_code{method="/users/123/profile", service="user-service"}
    • Good: 使用通用化的 method 标签,减少基数。
      status_code{method="GET", service="user-service"}

2.3 指标类型

Prometheus 支持以下几种主要的指标类型,每种类型有其特定的用途:

  • Counter (计数器): 用于表示某一事件发生的次数。计数器只能递增,或在重启时重置为零。

    • 示例: http_requests_total

httpRequestsTotal := prometheus.NewCounter(prometheus.CounterOpts{
  Name: "http_requests_total",
  Help: "Total number of HTTP requests.",
})
  • Gauge (仪表盘): 仪表用于记录可以增加或减少的数值,例如当前内存使用量、CPU 使用率等。适合用于表示系统的当前状态。

    • 示例: memory_usage_bytes

memoryUsage := prometheus.NewGauge(prometheus.GaugeOpts{
  Name: "memory_usage_bytes",
  Help: "Current memory usage in bytes.",
})
  • Histogram (直方图): 用于对事件发生的次数或数值进行分布统计,特别适用于测量延迟或请求大小。

    • 示例: http_request_duration_seconds_bucket

requestDurationHist := prometheus.NewHistogram(prometheus.HistogramOpts{
  Name:    "http_request_duration_seconds",
  Help:    "Duration of HTTP requests in seconds.",
  Buckets: prometheus.LinearBuckets(0.01, 0.05, 10), // 0.01s to 0.51s
})
  • Summary (摘要): 类似于 Histogram,但提供百分位数统计,适用于低采样率下的数据。

    • 示例: http_request_duration_seconds

2.4 标签 (Labels)

  • 标签命名: 标签的命名应遵循与指标类似的命名规范,使用小写字母和下划线 _。避免使用过多的标签,以减少指标的基数。

    • 示例: service, method, status

  • 标签值: 标签值应尽量少变化,并避免使用高基数的值(如用户 ID、请求 ID 等)。标签值应具备实际业务意义,并能够帮助区分不同维度的数据。

2.5 单位 (Units)

  • 单位标识: 在指标名称中显式包含单位,使用国际单位制 (SI) 的后缀。典型单位后缀包括:

    • 时间: _seconds

    • 大小: _bytes

    • 数量: _total

    • 百分比: _ratio_percent

  • 示例:

    • http_request_duration_seconds 表示 HTTP 请求的响应时间,单位为秒。

    • memory_usage_bytes 表示内存使用量,单位为字节。

三、自定义监控指标的实现

3.1 指标注册

在代码中自定义并注册指标时,应遵循以下步骤:

  1. 定义指标: 在服务启动时初始化和定义指标对象。选择适当的指标类型,并为其分配标签。

    示例 (Go 语言):
    ​
    var httpRequestDuration = prometheus.NewHistogramVec(
        prometheus.HistogramOpts{
            Name: "http_request_duration_seconds",
            Help: "HTTP request latency distributions.",
            Buckets: prometheus.DefBuckets,
        },
        []string{"method", "route"},
    )
    
    ​
    ​​​
  2. 注册指标: 将定义的指标注册到 Prometheus 默认的注册表中。
     

    prometheus.MustRegister(httpRequestDuration)
  3. 记录指标: 在代码逻辑中根据需要更新指标的值。

    timer := prometheus.NewTimer(httpRequestDuration.WithLabelValues("GET", "/api/v1/resource"))
    defer timer.ObserveDuration()

3.2 指标暴露

  • /metrics 端点:

    • 确保服务中的指标通过 /metrics 端点暴露,以供 Prometheus 抓取。

    • Prometheus 客户端库通常会自动处理这一部分,只需确保服务端点正确配置。

3.3 合理模块化与封装

封装指标创建

将指标的创建与初始化封装在一个独立的模块中,使代码更具可维护性和重用性

package metrics
import (
  "github.com/prometheus/client_golang/prometheus"
)
var (
  HttpRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
    Name: "http_requests_total",
    Help: "Total number of HTTP requests.",
  })
  MemoryUsage = prometheus.NewGauge(prometheus.GaugeOpts{
    Name: "memory_usage_bytes",
    Help: "Current memory usage in bytes.",
  })
  ...
)
func Init() {
  prometheus.MustRegister(HttpRequestsTotal, MemoryUsage)

3.4 优化打点性能

缓存和批处理

根据实际情况,适当缓存数据并进行批处理,减少对指标的频繁操作。

// Example of batch processing
func ProcessDataBatch(batch []Data) {
  start := time.Now()
  for _, data := range batch {
    process(data)
    metrics.DataProcessed.Inc()
  }
  duration := time.Since(start).Seconds()
  metrics.BatchProcessDuration.Observe(duration)
}
延迟操作

仅在必要时更新指标,尽量减少对性能的影响。

if needToUpdateMetrics {
  metrics.HttpRequestsTotal.Inc()

3.5 文档与注释

注释与文档

为每个指标添加适当的注释和文档,帮助其他开发者理解指标的用途和含义

// HttpRequestsTotal counts the total number of HTTP requests received.
var HttpRequestsTotal = prometheus.NewCounter(prometheus.CounterOpts{
  Name: "http_requests_total",
  Help: "Total number of HTTP requests received.",
})

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cloud孙文波

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值