您可以使用 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> ]
# 系列数据 [ 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_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>
Prometheus 允许不同的警报规则使用相同的警报名。因此,在此单元测试中,您必须在一个 <alert_test_case> 下列出警报名的所有触发警报的组合。
# 必须检查警报时,从 time=0s 开始经过的时间。 eval_time: <duration> # 要测试的警报名称。 alertname: <string> # 在给定评估时间内,在给定警报名称下触发的预期警报列表。 # 如果要测试某个警报规则是否不应该触发,则可以提及上述字段,并将 "exp_alerts "留空。 exp_alerts: [ - <alert> ]
# 这些是预期警报的扩展标签和注释。 # 注意:标签还包括与警报相关的样本标签(与在 `/alerts`中看到的相同, # 但不包括系列 `__name__` 和 `alertname`) exp_labels: [ <labelname>: <string> ] exp_annotations: [ <labelname>: <string> ]
# 要评估的表达式 expr: <string> # 从 time=0s 开始计算表达式的时间。 eval_time: <duration> # 给定评估时间内的预期样本。 exp_samples: [ - <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。
# 这是单元测试的主要输入。 # 只有该文件作为命令行参数传递。 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
# 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."