PrometheusPormQL语法及告警规则写法
这个是我⼀直不想写的,嫌⿇烦。还有就是这么多⼤神,我还差得远,不过是为了通过输出更好的理解这些知识。
介绍
Prometheus 是⼀个时序数据库,可以存储它通过 exporters 抓取回来的监控数据。那这些数据怎么去查询呢?⽐如MySQL有SQL语句,那Prometheus有啥呢? PromQL (Prometheus Query Language) ,这是Prometheus开发的数据查询DSL语⾔,⽇常的可视化以及告警规则都要⽤到它。这个很重要,⼀定得好好学⼀下。
举个例⼦
先拿Nginx的指标举个例⼦,Nginx如何监控,请查看我之前的⽂章
查看⼀台Nginx的活跃连接数,即active指标,如何看呢?
在服务器上查看完整的指标语句是:
[wonders@node1 ~]$ curl 172.18.11.192:9145/metrics
# HELP nginx_http_connections Number of HTTP connections
# TYPE nginx_http_connections gauge
nginx_http_connections{state="active"} 1349
nginx_http_connections{state="reading"} 0
nginx_http_connections{state="waiting"} 1341
nginx_http_connections{state="writing"} 5
......
那我只想看 active 怎么办呢?在输 PromQL 语句的地⽅输⼊
nginx_http_connections{state="active"}
会输出所有Nginx机器的 active
nginx_http_connections{instance="172.18.11.192:9145",job="Nginx",state="active"} 1459
nginx_http_connections{instance="172.18.11.193:9145",job="Nginx",state="active"} 1456
当我只想看其中⼀台⽐如192这台的时候呢?
nginx_http_connections{instance="172.18.11.192:9145",state="active"}
会输出192的指标
nginx_http_connections{instance="172.18.11.192:9145",job="Nginx",state="active"} 1358
是不是有点明⽩了?
当然线上不可能只有⼀台Nginx,那我想算总和呢?就是所有Nginx的active相加,这个基本需求PromQL早已实现。
sum(nginx_http_connections{state="active"})
输出结果如下
{} 2900
同样的 PromQL 还有sum (求和);min (最⼩值);max (最⼤值);avg (平均值);stddev (标准差);stdvar (标准差异);count (计数);
count_values (对 value 进⾏计数);bottomk (样本值最⼩的 k 个元素);topk (样本值最⼤的k个元素);quantile (分布统计),等等各种计算函数。这种在Prometheus叫做聚合操作。
这时有⼈说我不想看某⼀台机器的指标怎么办呢?使⽤ !=
nginx_http_connections{instance!="172.18.11.192:9145",state="active"}
这种操作符还有算数⼆次元运算符(加减乘除)、布尔运算符(= ,!= ,< , > ,<= ,>= )、集合运算符(and,or,unless)、匹配模式等等
看了上⾯的例⼦,应该有同学已经开窍了,下⾯的都是理论知识了。
理论知识
查询结果类型
PromQL 查询结果有下⾯4种类型:
即时数据 (Instant vector): ⼀组时间序列,每个时间序列包含⼀个样本,所有样本共享相同的时间戳,例如:http_requests_total
区间数据 (Range vector): 组时间序列,其中包含每个时间序列随时间的⼀系列数据点,例如:http_requests_total[5m]
纯量数据 (Scalar): 纯量只有⼀个数字,没有时序,例如:count(http_requests_total)
String-⼀个简单的字符串值;⽬前未使⽤
查询条件
Prometheus 存储的是时序数据,⽽它的时序是由名字和⼀组标签构成的,其实名字也可以写出标签的形式,例如http_requests_total等价于{name="http_requests_total"}。
⼀个简单的查询相当于是对各种标签的筛选,例如:
http_requests_total{code="200"} // 表⽰查询名字为 http_requests_total,code 为 "200" 的数据
查询条件⽀持正则匹配,例如:
http_requests_total{code!="200"}  // 表⽰查询 code 不为 "200" 的数据
http_requests_total{code=~"2.."} // 表⽰查询 code 为 "2xx" 的数据
http_requests_total{code!~"2.."} // 表⽰查询 code 不为 "2xx" 的数据
操作符
Prometheus 查询语句中,⽀持常见的各种表达式操作符,例如
正则匹配加减乘除算术运算符:
⽀持的算术运算符有+,-,*,/,%,^, 例如http_requests_total * 2表⽰将 http_requests_total 所有数据 double ⼀倍。
⽐较运算符:
⽀持的⽐较运算符有==,!=,>,<,>=,<=, 例如http_requests_total > 100表⽰ http_requests_total 结果中⼤于 100 的数据。
逻辑运算符:
⽀持的逻辑运算符有and,or,unless, 例如http_requests_total == 5 or http_requests_total == 2表⽰ http_requests_total 结果中等于 5 或者 2 的数据。聚合运算符:
⽀持的聚合运算符有sum,min,max,avg,stddev,stdvar,count,count_values,bottomk,topk,quantile,, 例如max(http_requests_total)表⽰
http_requests_total 结果中最⼤的数据。
注意,和四则运算类型,Prometheus 的运算符也有优先级,它们遵从(^)> (*, /, %) > (+, -) > (==, !=, <=, <, >=, >) > (and, unless) > (or) 的原则。
内置函数
Prometheus 内置不少函数,⽅便查询以及数据格式化,例如将结果由浮点数转为整数的 floor 和 ceil,
floor(avg(http_requests_total{code="200"}))
ceil(avg(http_requests_total{code="200"}))
查看 http_requests_total 5分钟内,平均每秒数据
rate(http_requests_total[5m])
告警规则
看了前⾯的知识,现在知道如何取指标了,那告警怎么做呢?还是先举个例⼦
在 Zabbix上告警怎么做的?⽐如单台Nginx active指标超过1w就要发出告警,触发器那⾥选的是Nginx active项,然后选⼤于10000,触发告警。
Prometheus 也是⼀样啊,你⽤如下语句获取当前值
nginx_http_connections{instance="172.18.11.192:9145",state="active"}
前⾯说了PromQL⽀持⽐较运算符,那告警规则就这么写
nginx_http_connections{instance="172.18.11.192:9145",state="active"} > 10000
简单吧。。。如下为完整的告警规则
groups:
- name: Nginx
rules:
- alert: HighErrorRate
expr: nginx_http_connections{instance="172.18.11.192:9145",state="active"} > 10000    for: 5m
labels:
severity: page
annotations:
summary: "啊啊啊啊啊,(instance {{ $labels.instance }}) 连接数超1w了"
description: "Nginx 连接数现在 VALUE = {{ $value }}\n  LABELS: {{ $labels }}"
#group:定义⼀组相关规则
#alert:告警规则名称
#expr:基于PromQL的触发条件
#for 等待评估时间
#label ⾃定义标签
#annotation:指定⼀组附加信息Alertmanger特性
下⼀篇写 Prometheus 如何做告警。。。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。