Prometheus 教程

Prometheus 规则单元测试

您可以使用 promtool 测试您的规则,如下:

# 对于单个测试文件
./promtool test rules test.yml

# 如果有多个测试文件,例如 test1.yml,test2.yml,test2.yml
./promtool test rules test1.yml test2.yml test3.yml

测试文件格式

# 这是一份测试规则文件列表,支持全局
rule_files:
  [ - <file_name> ]

[ evaluation_interval: <duration> | default = 1m ]

# 下面列出的组名顺序将是规则组的评估顺序(在给定的评估时间)。
# 只有下面提到的组才能保证顺序,不一定要在下面列出所有规则组。
group_eval_order:
  [ - <group_name> ]

# 这里列出了所有测试
tests:
  # 见 <test_group> 章节
  [ - <test_group> ]

<test_group>

# 系列数据
[ interval: <duration> | default = evaluation_interval ]
input_series:
  # 见 <series> 章节
  [ - <series> ]

# 测试组名称
[ name: <string> ]

# 对上述数据进行单元测试。

# 警报规则的单元测试。我们考虑的是输入文件中的警报规则。
alert_rule_test:
  # 见 <alert_test_case> 章节
  [ - <alert_test_case> ]

# PromQL 表达式的单元测试
promql_expr_test:
  # 见 <promql_test_case> 章节
  [ - <promql_test_case> ]

# 警报模板可访问的外部标签。
external_labels:
  [ <labelname>: <string> ... ]

# 警报模板可访问的外部 URL。
# 通常使用 --web.external-url 设置。
  [ external_url: <string> ]

<series>

# 这遵循通常的系列符号 "<指标名称>{<标注名称>=<标注值>, ...}"
# 示例:
#      series_name{label1="value1", label2="value2"}
#      go_goroutines{job="prometheus", instance="localhost:9090"}
series: <string>

# 这使用的是扩展符号。
# 扩展符号:
# 	'a+bxn' 变成 'a a+b a+(2*b) a+(3*b) ... a+(n*b)'
# 	读作序列从 a 开始,然后以 b 为单位递增 n 个样本。
# 	'a-bxn' 变成 'a a-b a-(2*b) a-(3*b) ... a-(n*b)' 
# 	读作序列从 a 开始,然后 n 个样本按 b 递减(或按负 b 递增)。
# 	'axn' 变成 'a a a ... a'(a 的 n+1 次方),这是'a+0xn'的简称
# 有一些特殊值用于表示样本缺失和过期:
#     '_' 代表从抓取中缺少的样本
#     'stale' 表示样本过期
# 示例:
# 	1. '-2+4x3' 变为 '-2 2 6 10',系列从-2 开始,然后是以 4 为增量的 3 个样本。
#	  2. '1-2x4' 变为 '1 -1 -3 -5 -7',系列从 1 开始,然后 4 个样本递减 2。
# 	3. '1x4' 变为 '1 1 1 1',是 '1+0x4' 的缩写,系列从 1 开始,然后 4 个样本递增 0。
# 	4. '1 _x3 stale' 变为 '1 _ _ _ stale',缺少的样本不能递增,因此 '_x3' 表达式产生了 3 个缺少的样本。
#
# 本地直方图符号:
# 	可以使用以下符号代替浮点数使用本地直方图:
#  	{{schema:1 sum:-0.3 count:3.1 z_bucket:7.1 z_bucket_w:0.05 buckets:[5.1 10 7] offset:-3 n_buckets:[4.1 5] n_offset:-5}}
# 	本地直方图支持与浮点数相同的扩展符号,即 "axn"、"a+bxn "和 "a-bxn"。
# 	所有属性都是可选的,默认值为 0。支持以下属性
#     - schema (int): 
#         目前有效的模式编号为-4 <= n <= 8。它们都是以 2 为底的水桶模式,
#					其中 1 是每个水桶的边界,然后每个 2 的幂次分为 2^n 个对数水桶。 
#					或者换句话说,每个水桶边界都是前一个边界乘以 2^(2^-n)。
#     - sum (float): 
#         包括零桶在内的所有观测值的总和。
#     - count (non-negative float): 
#         观测值的数量,包括 NaN 和零桶。
#     - z_bucket (non-negative float): 
#         零桶中所有观测值的总和。
#     - z_bucket_w (non-negative float): 
#         零桶的宽度。
#         如果 z_bucket_w > 0,则零数据桶包含所有观测值 -z_bucket_w <= x <= z_bucket_w。
#					否则,零数据桶只包含精确为 0 的观测值。
#     - buckets (list of non-negative floats):
#         正数桶中的观测值计数。每个都代表一个绝对计数。
#     - offset (int):
#         正数据桶中第一个条目的起始索引。
#     - n_buckets (list of non-negative floats):
#         负数桶中的观测值计数。每个计数代表一个绝对计数。
#     - n_offset (int):
#         负数据桶中第一个条目的起始索引。
values: <string>

<alert_test_case>

Prometheus 允许不同的警报规则使用相同的警报名。因此,在此单元测试中,您必须在一个 <alert_test_case> 下列出警报名的所有触发警报的组合。

# 必须检查警报时,从 time=0s 开始经过的时间。
eval_time: <duration>

# 要测试的警报名称。
alertname: <string>

# 在给定评估时间内,在给定警报名称下触发的预期警报列表。
# 如果要测试某个警报规则是否不应该触发,则可以提及上述字段,并将 "exp_alerts "留空。
exp_alerts:
  [ - <alert> ]

<alert>

# 这些是预期警报的扩展标签和注释。
# 注意:标签还包括与警报相关的样本标签(与在 `/alerts`中看到的相同,
# 	但不包括系列 `__name__` 和 `alertname`)
exp_labels:
  [ <labelname>: <string> ]
exp_annotations:
  [ <labelname>: <string> ]

<promql_test_case>

# 要评估的表达式
expr: <string>

# 从 time=0s 开始计算表达式的时间。
eval_time: <duration>

# 给定评估时间内的预期样本。
exp_samples:
  [ - <sample> ]

<sample>

# 用通常的系列符号"<度量名称>{<标签名称>=<标签值>, ...}"表示样本的标签
# 示例:
#      series_name{label1="value1", label2="value2"}
#      go_goroutines{job="prometheus", instance="localhost:9090"}
labels: <string>

# PromQL 表达式的预期值。
value: <number>

示例

这是一个通过测试的单元测试输入文件示例。test.yml 是按照上述语法编写的测试文件,alerts.yml 包含警报规则。

将 alerts.yml 和 promtool 工具放在同一目录下,运行 ./promtool test rules test.yml。

test.yml

# 这是单元测试的主要输入。
# 只有该文件作为命令行参数传递。

rule_files:
    - alerts.yml

evaluation_interval: 1m

tests:
    # 测试1
    - interval: 1m
      # 系列数据
      input_series:
          - series: 'up{job="prometheus", instance="localhost:9090"}'
            values: '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0'
          - series: 'up{job="node_exporter", instance="localhost:9100"}'
            values: '1+0x6 0 0 0 0 0 0 0 0' # 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
          - series: 'go_goroutines{job="prometheus", instance="localhost:9090"}'
            values: '10+10x2 30+20x5' # 10 20 30 30 50 70 90 110 130
          - series: 'go_goroutines{job="node_exporter", instance="localhost:9100"}'
            values: '10+10x7 10+30x4' # 10 20 30 40 50 60 70 80 10 40 70 100 130

      # 报警规则的单元测试
      alert_rule_test:
          # 单元测试1
          - eval_time: 10m
            alertname: InstanceDown
            exp_alerts:
                # 报警1
                - exp_labels:
                      severity: page
                      instance: localhost:9090
                      job: prometheus
                  exp_annotations:
                      summary: "Instance localhost:9090 down"
                      description: "localhost:9090 of job prometheus has been down for more than 5 minutes."
      
      # promql表达式的单元测试
      promql_expr_test:
          # 单元测试1
          - expr: go_goroutines > 5
            eval_time: 4m
            exp_samples:
                # 样本1
                - labels: 'go_goroutines{job="prometheus",instance="localhost:9090"}'
                  value: 50
                # 样本2
                - labels: 'go_goroutines{job="node_exporter",instance="localhost:9100"}'
                  value: 50

alerts.yml

# This is the rules file.

groups:
- name: example
  rules:

  - alert: InstanceDown
    expr: up == 0
    for: 5m
    labels:
        severity: page
    annotations:
        summary: "Instance {{ $labels.instance }} down"
        description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."

  - alert: AnotherInstanceDown
    expr: up == 0
    for: 10m
    labels:
        severity: page
    annotations:
        summary: "Instance {{ $labels.instance }} down"
        description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."


说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号