Prometheus
1.部署安装prometheus
二进制安装
1 | https://github.com/prometheus/prometheus/releases/download/v3.13.1/prometheus-3.13.1.linux-amd64.tar.gz |
创建service文件
1 | [root@mongo1 local]# cat /lib/systemd/system/prometheus.service |
[root@mongo1 local]# curl -X POST localhost:9090/-/reload
# 重新加载配置
1 | [root@mongo1 prometheus]# promtool check config /usr/local/prometheus/conf/prometheus.yml |
2.node_exporter
1 | tar xf node_exporter-1.12.1.linux-amd64.tar.gz -C /usr/local/ |
prometheus增加配置
1 | [root@mongo1 ~]# cat /usr/local/prometheus/conf/prometheus.yml |
3.Grafana
二进制安装
下载二进制包
1 | wget https://dl.grafana.com/grafana-enterprise/release/13.1.1/grafana-enterprise_13.1.1_29761037902_linux_amd64.tar.gz |
http://192.168.11.4:3000/dashboards
登录Grafana 默认用户名/密码 admin/admin
配置Data Source
Prometheus 增加grafana
1 | - job_name: "grafana" |
1 | curl -X POST localhost:9090/-/reload |
3.1Grafana 导入dashboard
https://grafana.com/grafana/dashboards/
new dashboard – import dashboard
NodeExporter

4.Pushgateway 采集自定义数据
4.1 Pushgateway介绍
Pushgateway是一项中介或代理服务,允许您从无法抓取的作业中推送指标
虽然有很多的Exporter提供了丰富的数据,但生产环境中仍需要采集用户自定义的数据,可以利用Pushgateway实现
Pushgateway 是另一种采用客户端主动推送数据的方式也可以获取监控数据的prometheus 插件
Pushgateway与exporter 不同,Exporter 是被动采集数据
Pushgateway可以单独运行在任何节点上,并不一定要在被监控客户端安装
用户自定义的脚本或程序将需要监控的数据推送给 Pushgateway,然后prometheus server再向pushgateway拉取数据
缺点:
pushgateway会形成一个单点瓶颈,假如好多个应用同时发送给一个pushgateway的进程,如果这个进程有故障,那么监控数据也就无法获取了。
将失去prometheus通过up指标(每次抓取时生成)的自动实例运行状况监控
pushgateway永远不会忘记推送给它的数据,并将
官方链接:https://prometheus.io/docs/practices/pushing/
4.2 安装Pushgateway
二进制安装
1 | tar -xf pushgateway-1.11.3.linux-amd64.tar.gz -C /usr/local/ |
配置prometheus 收集pushgateway数据
1 | - job_name: "pushgateway" |
配置客户端发送数据给pushgateway
https://github.com/prometheus/pushgateway/blob/master/README.md
xamples:
Push a single sample into the group identified by
{job="some_job"}:1
echo "some_metric 3.14" | curl --data-binary @- http://192.168.11.4:9091/metrics/job/some_job
Since no type information has been provided,
some_metricwill be of typeuntyped.Push something more complex into the group identified by
{job="some_job",instance="some_instance"}:1
2
3
4
5
6
7cat <<EOF | curl --data-binary @- http://192.168.11.4:9091/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric2{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
EOFNote how type information and help strings are provided. Those lines are optional, but strongly encouraged for anything more complex.
Delete all metrics in the group identified by
{job="some_job",instance="some_instance"}:1
curl -X DELETE http://pushgateway.example.org:9091/metrics/job/some_job/instance/some_instance
Delete all metrics in the group identified by
{job="some_job"}(note that this does not include metrics in the{job="some_job",instance="some_instance"}group from the previous example, even if those metrics have the same job label):1
curl -X DELETE http://pushgateway.example.org:9091/metrics/job/some_job
Delete all metrics in all groups (requires to enable the admin API via the command line flag
--web.enable-admin-api):1
curl -X PUT http://pushgateway.example.org:9091/api/v1/admin/wipe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27[root@mongo1 ~]# cat pushgateway_metric.sh
#!/bin/bash
METRIC_NAME=login_number
METRIC_VALUE_CMD="who | wc -l"
METRIC_TYPE=gauge
METRIC_HELP="login use number"
PUSHGATEWAY_HOST=192.168.11.4:9091
EXPORTED_JOB=pushgateway_job
INSTANCE=`hostname -I|awk '{print $1}'`
SLEEP_TIME=1
CURL_URL="curl --data-binary @- http://${PUSHGATEWAY_HOST}/metrics/job/${EXPORTED_JOB}/instance/${INSTANCE}"
push_metric() {
while true ;do
VALUE=`eval "$METRIC_VALUE_CMD"`
cat <<EOF | $CURL_URL
# HELP ${METRIC_NAME} ${METRIC_HELP}
# TYPE ${METRIC_NAME} ${METRIC_TYPE}
${METRIC_NAME} ${VALUE}
EOF
sleep $SLEEP_TIME
done
}
push_metric
5.PromQL
5.1指标数据
5.1.1 数据基础
时间序列数据:
按照时间顺序记录系统、设备状态变化的数据,每个数据称为一个样本
数据采集以特定的时间周期进行,随着时间将这些样本数据记录下来,将生成一个离散的样本数据序列,该序列也称为向量(Vector)
将多个序列放在同一个坐标系内(以时间为横轴,以序列为纵轴),将形成一个由数据点组成的矩阵
Prometheus基于指标名称(metrics name)以及附属的标签集(labelset)唯一定义一条时间序列
指标名称代表着监控目标上某类可测量属性的基本特征标识
标签则是这个基本特征上再次细分的多个可测量维度
5.1.2 数据模型
Prometheus中,每个时间序列都由指标名称(Metric Name)和标签(Label)来唯一标识Metric Name的表示方式有下面两种
metric name>{
指标名称: 通常用于描述系统上要测定的某个特征 支持使用字母、数字、下划线和冒号,且必须能匹配RE2规范的正则表达式 例如:http_requests_total表示接收到的HTTP请求总数 标签: 键值型数据,附加在指标名称之上,从而让指标能够支持更多细化的多纬度特征;此为可选项标签名称可使用字母、数字和下划线,且必须能匹配RE2规范的正则表达式 注意:以两个下划线 "__" 为前缀的名称为Prometheus系统预留使用
不同的时间序列
1 | http_requests_total{method=GET} |
5.1.3 样本数据
Prometheus的每个数据样本由两部分组成
- key: 包括三部分Metric 名称,Label, Timestamp(毫秒精度的时间戳)
- value: float64格式的数据
PromQL支持基于定义的指标维度进行过滤,统计和聚合
指标名称和标签的特定组合代表着一个时间序列
不同的指标名称代表着不同的时间序列
指标名称相同,但标签不同的组合分别代表着不同的时间序列
更改任何标签值,包括添加或删除标签,都会创建一个新的时间序列
应该尽可能地保持标签的稳定性,否则,则很可能创建新的时间序列,更甚者会生成一个动态的数据环境,并使得监控的数据源难以跟踪,从而导致建立在该指标之上的图形、告警及记录规则变得无效
5.2 PromQL基础
5.2.1 PromQL简介
Prometheus 提供一个内置的函数式的表达式语言PromQL(Prometheus Query Language),可以帮助用户实现实时地查找和聚合时间序列数据。
PromQL表达式计算结果可以在图表中展示,也可以在Prometheus表达式浏览器中以表格形式展示,或者作为数据源, 以HTTP API的方式提供给外部系统使用。
注意:默认情况下,是以当前时间为基准点,来进行数据的获取操作
5.2.2 表达式形式
官方文档
·https://prometheus.io/docs/prometheus/latest/querying/basics/·
每一个PromQL其实都是一个表达式,这些语句表达式或子表达式的计算结果可以为以下四种类型:
- instant vector 即时向量,瞬时数据
具有相同时间戳的一组样本值的集合
在某一时刻,抓取的所有监控项数据。这些度量指标数据放在同一个key中。
一组时间序列,包含每个时间序列的单个样本,所有时间序列共享相同的时间戳 - range vector 范围向量
指定时间范围内的所有时间戳上的数据指标,即在一个时间段内,抓取的所有监控项数据。一组时间序列,其中包含每个时间序列随时间变化的一系列数据点 - scalar 标量
- 一个简单的浮点类型数值
- string 字符串
可用内存占用率
node_memory_MemFree_bytes/node_memory_MemTotal_bytes*100
内存占用率
(node_memory_MemTotal_bytes-node_memory_MemFree_bytes)/node_memory_MemTotal_bytes*100
内存占用率是否大于80
node_memory_MemFree_bytes)/node_memory_MemTotal_bytes*100 > bool 80
1 | curl 192.168.11.4:9090/status |
5.3 PromQL运算
https://prometheus.io/docs/prometheus/latest/querying/operators/
5.3.1 二元运算符
二元运算符是prometheus进行数据可视化或者数据分析操作的时候,应用非常多的一种功能对于二元运算符来说,它主要包含三类:算术、比较、逻辑
#算术运算符:+(addition)
-(subtraction)
*(multiplication)
/ (division)
% (modulo)
^ (power/exponentiation)
#比较运算符:
== (equal)
!= (not-equal)>(greater-than)
< (less-than)
>= (greater-or-equal)
<= (less-or-equal)
#逻辑运算符:
and、or、unless
#目前该运算符仅允许在两个即时向量之间进行操作,不支持标量(标量只有一个数字,没有时序)参与运算#运算符从高到低的优先级
1 ^
2 *, /, %
3 +, -
4 ==, !=, <=, <, >=, >
5 and, unless
6 or
#注意:
#具有相同优先级的运算符满足结合律(左结合),但幂运算除外,因为它是右结合机制
#可以使用括号()改变运算次序
5.3.2 聚合操作
一般说来,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标,这种联合机制是指”聚合”操作,例如,将计数、求和、平均值、分位数、标准差及方差等统计函数应用于时间序列的样本之上生成具有统计学意义的结果等
对查询结果事先按照某种分类机制进行分组(groupby)并将查询结果按组进行聚合计算也是较为常见的需求,例如分组统计、分组求平均值、分组求和等
聚合操作由聚合函数也称为聚合操作符针对一组值进行计算并返回单个值或少量值作为结果
聚合操作符aggregation operators虽然是一个个的功能,但是并不属于功能函数,仅仅代表对数据进行简单的功能处理。
常见的11种聚合操作:sum、min、max、avg、count、count_values(值计数)
stddev(标准差)、stdvar(标准差异)、bottomk(最小取样)、topk(最大取样,即取前几个)、quantile(分布统计)
sum() #对样本值求和
avg() #对样本值求平均值,这是进行指标数据分析的标准方法
count()#对分组内的时间序列进行数量统计
min()#求取样本值中的最小者
max()#求取样本值中的最大者
topk()#逆序返回分组内的样本值最大的前k个时间序列及其值
bottomk()#顺序返回分组内的样本值最小的前k个时间序列及其值
quantile()#分位数用于评估数据的分布状态,该函数会返回分组内指定的分位数的值,即数值落在小于等于指定的分位区间的比例
count_values()#对分组内的时间序列的样本值进行数量统计
stddev() #对样本值求标准差,以帮助用户了解数据的波动大小(或称之为波动程度)
stdvar() #对样本值求方差,它是求取标准差过程中的中间状态
格式:
聚合操作符(metric表达式) sum、min、max、avg、count等
聚合操作符(描述信息,metric) count_values、bottomk、topk等
可以借助于without和by功能获取数据集中的一部分进行分组统计
#without 表示显示信息的时候,排除此处指定的标签列表,对以外的标签进行分组统计,即:使用除此标签之外的其它标签进行分组统计
#by表示显示信息的时候,仅显示指定的标签的分组统计,即针对哪些标签分组统计
1 | #显示系统版本 |
5.3.3 功能函数
https://prometheus.io/docs/prometheus/latest/querying/functions/
默认prometheus官方提供功能函数有40个,主要有以下几类
计算相关
绝对值abs()、导数deriv()、指数exp()、对数ln()、二进制对数log2()、10进制对数log10()、平方根sqrt()
向上取整ceil()、向下取整floor()、四舍五入round()
样本差idelta()、差值delta()、递增值increase()、重置次数resets()
递增率irate()、变化率rate()、平滑值holt_winters()、直方百分位histogram_quantile()
预测值predict_linear()、参数vector()
范围最小值min_over_time()、范围最大值max_over_time()、范围平均值avg_over_time()、范围求和值sum_over_time()、范围计数值count_over_time()、范围分位数quantile_over_time()、范围标准差stddev_over_time()、范围标准方差stdvar_over_time()
取样相关
获取样本absent()、升序sort()、降序sort_desc()、变化数changes()即时数据转换为标量scalar()、判断大clamp_max()、判断小clamp_min()范围采样值absent_over_time(),
时间相关
day_of_month()、day_of_week()、days_in_month()、hour()、minute()、month()、time()、 timestamp()、year()
标签相关
标签合并label_join()、标签替换labelreplace()
示例:
ceil():向上取整 floor():向下取整round():四舍五入
#示例
ceil(node_load15 * 10)
floor(node_load15 * 10)
round(node_load15 * 10)
increase(): 增长量,即last值-last前一个值
#示例:最近1分钟内CPU处于空闲状态时间
increase(node_cpu_seconds_total{cpu=’0’,mode=’idle’}[1m])
#示例:CPU利用率
(1 - sum(increase(node_cpu_seconds_total{mode=”idle”}[1m])) by (instance) /
sum(increase(node_cpu_seconds_total[1m])) by (instance)) * 100
rate():
#平均变化率,计算在指定时间范围内计数器每秒增加量的平均值,即(last值-first值)/时间差的秒数,常用于counter的数据#示例:过去一分钟每次磁盘读的变化率
rate(node_disk_read_bytes_total[1m])
#示例:一分钟内网卡传输的字节数(MB)
rate(node_network_transmit_bytes_total{device=”eth0”}[1m]) /1024 /1024
#判断在过去5分钟内HTTP请求状态码以”5”开头的请求的速率是否大于所有HTTP请求速率的10%。
rate(http_requests_total{status_code=~”5.*”}[5m]) > rate(http_requests_total[5m])*0.1
#每台主机CPU在5分钟内的平均使用率
(1- avg(irate(node_cpu_seconds_total{mode=’idle’}[5m])) by (instance))*100irate():查看瞬时变化率,即:(last值-last前一个采样的值)/时间戳差值
#高灵敏度函数,用于计算指标的瞬时速率,常用于counter的数据
#示例:过去一分钟每次磁盘读的瞬时变化率
irate(node_disk_read_bytes_total[1m])
#示例:查看CPU最近5m内最多的增长率
irate(node_cpu_seconds_total{instance=”10.0.0.101:9100”,mode=”idle”}[5m])
#irate和rate都会用于计算某个指标在一定时间间隔内的变化速率。但是它们的计算方法有所不同:irate取的是在指定时间范围内的最近两个数据点来算速率,而rate会取指定时间范围内所有数据点,算出一组速率,然后取平均值作为结果。所以官网文档说:irate适合快速变化的计数器(counter),而rate适合缓慢变化的计数器
(counter)。对于快速变化的计数器,如果使用rate,因为使用了平均值,很容易把峰值削平。除非我们把时间间隔设置得足够小,就能够减弱这种效应。time(): 获取当前时间值
#示例:计算当前每个主机的运行时间
(time() - node_boot_time_seconds) / 3600
#示例:计算所有主机的总运行时间
sum(time() - node_boot_time_seconds) / 3600
histogram_quantile(): 百分取样值
#示例:计算过去10m内请求持续时间的第90个百分位数
histogram_quantile(0.9, rate(prometheus_http_request_duration_seconds_bucket[10m]))
#absent 有值返回空,无值返回1,可用于告警判断
absent(node_memory_SwapTotal_bytes)
absent(node_memory_SwapTotal_byte)
5.4 定制Exporter python实现
1 |
|
# curl -s localhost:8001/metrics
{“return”:”success OK!”}
修改prometheus文件
1 | - job_name: "flask" |

1 | rate(request_count_total[1m]) |
rate = (value_end - value_start) / 时间窗口秒数
6.标签管理
标签功能: 用于对数据分组和分类,利用标签可以将数据进行过滤筛选
标签管理的常见场景:
- 删除不必要的指标
- 从指标中删除敏感或不需要的标签
- 添加、编辑或修改指标的标签值或标签格式
标签分类:
- 默认标签: Prometheus 自身内置
形式: _keyname_
应用标签: 应用本身内置
形式: keyname
自定义标签: 用户定义
形式: keyname
6.1 添加主机节点查看默认标签
1 | - job_name: "flask" |

6.2 指标的生命周期
标签主要有两种表现形式:
- 私有标签
私有标签以”__*”样式存在,用于获取监控目标的默认元数据属性,比如__address__用于获取目标的地址, __scheme__用户获取目标的请求协议方法,__metrics_path__获取请求的url
- 普通标签
对个监控主机节点上的监控指标进行各种灵活的管理操作,常见的操作有,删除不必要|敏感指标,添加、编辑或者修改指标的标签值或者标签格式。
在prometheus的配置选项中,有两个与监控指标密切相关的配置,relabel_config、
metric_relabel_configs,它们的作用就是监控目标上面的监控项进行标签管理和设置,便于在prometheus上设置更灵活的时序数据。
prometheus对数据的处理流程:
服务发现 –> 配置 –> 重新标记relabel_configs –> 抓取 –>重新标记 metircs_relabel_configs
在每个scrape_interval期间,Prometheus都会检查执行的作业 Job
这些作业首先会根据Job上指定的发现配置生成target列表,此即服务发现过程
服务发现会返回一个Target列表,其中包含一组称为元数据的标签,这些标签都以 “_meta“为前缀__服务发现还会根据目标配置来设置其它标签,这些标签带有 “__”前缀和后缀,包括如下:
1 | "__scheme__" #协议http或https,默认为http |
6.3 relabel_configs和relabel_configs
| 区别 | 解析 |
|---|---|
| 执行顺序 | relabel_configs用与scrape目标上metric前的标签设置,也就是说在scrape_configs前生效,针对的是target对象本身 metric_relabel_configs 作用于scrape_configs 生效后,即针对target对象上的metric监控数据 |
| 数据处理 | metric_relabel_configs 是 prometheus 在保存数据前的最后一步标签重新编辑,针对的是metric对象 默认情况下,它将监控不需要的数据,直接丢掉,不在prometheus 中保存 |
对target重新打标
对target重新打标是在数据抓取之前动态重写target标签的强大工具
在每个数据抓取配置中,可以定义多个relabel步骤,它们将按照定义的顺序依次执行对于发现的每个target,Prometheus默认会执行如下操作
1 | job的标签设定为配置文件中其所属的job_name的值 |
6.4 标签管理
对于一些全局性的标签,可以在global部分通过属性来设置,格式如下:
1 | global: |
官方文档:
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs
relabel_config、metric_relabel_configs 的使用格式基本上一致常见配置如下
1 | #配置示例如下: |
属性解析:
action 对标签或指标进行管理,常见的动作有
replace|keep|drop|labelmap|labeldrop等,默认为replace
source_labels #指定正则表达式匹配成功的Label进行标签管理,此为列表
target_label #在进行标签替换的时候,可以将原来的source_labels替换为指定修改后的目标
label
separator #指定用于联接多个source_labels为一个字符串的分隔符,默认为分号
regex #表示source_labels对应Label的名称或者值(和action有关)进行匹配
replacement # #替换标签时,将 target_label对应的值进行修改成此处的值
#action说明:
#1)替换标签的值:replace #此为默认值,首先将source labels中指定的各标签的值使用separator指定的字符进行串连,如果串连后的值和regex匹配,则使用replacement指定正则表达式模式或值对target_label字段进行赋值,如果target_label不存在,也可以用于创建新的标签名为target_label
hashmod #将target_label的值设置为一个hash值,该hash是由modules字段指定的hash模块算法对source_labels上各标签的串连值进行hash计算生成
#2)保留或删除指标: 该处的每个指标名称对应一个target或metrickeep 如果获取指标的source_labels的各标签的值串连后的值与regex匹配时,则保留该指标,反之则删除该指标
drop #如果获取指标的source_labels的各标签的值串连后的值与regex匹配时,则删除该指标,反之则保留该指标,即与keep相反
#3)创建或删除标签
labeldrop #如果source labels中指定的标签名称和regex相匹配,则删除此标签,相当于标签黑名单labelkeep #如果source labels中指定的标签名称和regex相匹配,则保留,不匹配则删除此标签,相当于标签白名单labelmap #一般用于生成新标签,将regex对source labels中指定的标签名称进行匹配,而后将匹配到的标签的值赋值给replacement字段指定的标签;通常用于取出匹配的标签名的一部分生成新标签,旧的标签仍会存在
#4)大小写转换
lowercase #将串联的 source_labels 映射为其对应的小写字母uppercase #将串联的 source_labels 映射到其对应的大写字母
replace 的完整流程
action: replace # 默认动作
source_labels: […] # 指定要读取哪些”标签”
separator: “;” # 拼接这些标签的”值”时用的分隔符(默认;)
regex: “…” # 用来匹配上面拼接出来的”值”字符串
replacement: “…” # 用捕获组拼出新内容
target_label: “…” # 把 replacement 的结果写入这个”标签”
1 | relabel_configs: |
这段
relabel_configs用的是action: labelmap,和之前replace的行为完全不同——它匹配的是标签名(label name),而不是标签值(label value)。action: labelmap 的工作原理
- 匹配对象:Prometheus 会拿现有的每一个标签名去和
regex做匹配(这里没写source_labels,labelmap默认就是对所有已存在的标签名进行匹配,不需要指定 source)。- 匹配成功后:会新建一个标签,新标签名 =
replacement(用捕获组填充),新标签的值 = 原标签的值(也就是复制一份,不是删除原标签,是新增)。
1 | - regex: "(job|app)" |
这个和 labelmap 类似,都是匹配标签名,但作用完全相反——它是删除标签,不是新增。
1 | - regex: "(job|app)" |
action: labeldrop 的工作原理
- 匹配对象:和
labelmap一样,是已存在的标签名(同样不需要source_labels,会遍历所有当前标签名去匹配)。 - 匹配成功后:直接删除这个标签(连标签名带值一起丢弃)。
- 不需要
replacement或target_label,因为它不产生新标签。
这是 metric_relabel_configs,和之前的 relabel_configs 作用阶段不同
| relabel_configs | metric_relabel_configs | |
|---|---|---|
| 执行时机 | 抓取之前,作用于**目标(target)**本身 | 抓取之后,样本数据已经拿到手,落盘存储之前 |
| 能操作的标签 | __address__、__scheme__、__metrics_path__ 等 target 元标签 |
抓取到的每一条指标样本上的标签,包括 __name__(指标名本身) |
| 典型用途 | 决定抓哪个目标、怎么抓、加什么标签 | 过滤/修改具体抓回来的指标数据,比如丢弃某些指标、脱敏某些标签值 |
metric_relabel_configs
1 | metric_relabel_configs: |
7.记录和告警
prometheus 支持两种类型的规则:
- 记录规则
- 警报规则
它们可以进行配置,然后定期进行评估。 要将规则包含在Prometheus中,需要先创建一个包含必要规则语句的文件,并让Prometheus通过Prometheus配置中的rule_fies字段加载该文件。 默认情况下, prometheus的规则文件使用YAML格式
规则的使用流程:
- 首先创建一个满足规则标准的规则语句,然后发送SIGHUP给Prometheus进程
- prometheus在运行时重新加载规则文件,从而让规则在prometheus运行环境中生效
规则语法检查:
1 | #promtool check rules prometheus_rues_file.yml |
7.1记录规则说明
https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/
在Prometheus的表达式浏览器进行的查询会生成的新的数据序列,但其结果仅会临时保存于Prometheus Server上
在样本数据量较大、工作较为繁忙的Prometheus Server上,对于那些查询频率较高且运算较为复杂的查询来说,实时查询可能会存在一定程度的响应延迟
记录规则的作用其实将之前的监控命令采用配置文件的方式进行编写,从而大大减轻工作量
记录规则(Recording rule)能够预先运行频繁用到或计算消耗较大的表达式,并将其结果保存为一组新的时间序列
记录规则是定义在Prometheus配置文件中的查询语句,由Server加载后以类似批处理任务的方式在后台周期性(evaluation_interval)的执行并记录查询结果
客户端只需要查询由记录规则生成的结果序列上的样本数据即可,速度远快于实时查询;常用于跨多个时间序列生成聚合数据,或者计算消耗较大的查询等场景中
多见于同可视化工具结合使用的需求中,也可用于生成可产生告警信息的时间序列记录规则常用的场景:
将预先计算经常需要或计算量大的复杂的PromQL语句指定为一个独立的metric监控项,这样在查询的时候就非常方便,而且查询预计算结果通常比每次需要原始表达式都要快得多,尤其是对于仪表板特别有用,仪表板每次刷新时都需要重复查询相同的表达式。
此外在告警规则中也可以引用记录规则
记录规则效果与shell中的别名相似
规则存放路径
1 | mkdir -p /usr/local/prometheus/rules |


8.告警说明和Alertmanager
8.1告警说明
8.1.1 告警介绍
官方文档:
https://prometheus.io/docs/alerting/latest/overview/
Prometheus作为一个大数据量场景下的监控平台来说,数据收集是核心功能,虽然监控数据可视化了,也非常容易观察到运行状态。但是最能产生价值的地方就是对数据分析后的告警处理措施,因为我们很难做到时刻盯着监控并及时做出正确的决策,所以程序来帮巡检并自动告警,是保障业务稳定性的决定性措施。可以说任何一个监控平台如果没有告警平台,那么他就逊色不少甚至都不能称之为平台。
Prometheus报警功能主要是利用Alertmanager这个组件来实现功能的。Alertmanager作为一个独立的组件,负责接收并处理来自Prometheus Server(也可以是其它的客户端程序)的告警信息。Alertmanager可以对这些告警信息进行进一步的处理,比如当接收到大量重复告警时能够消除重复的告警信息,同时对告警信息进行分组并且路由到正确的通知方,Prometheus内置了对邮件,Slack等多种通知方式的支持,同时还支持与Webhook的集成,以支持更多定制化的场景。
8.1.2 告警组件
告警能力在Prometheus的架构中被划分成两个独立的部分。
- 通过在Prometheus中定义AlertRule(告警规则),Prometheus会周期性的对告警规则进行计算,如果满足告警触发条件就会向Alertmanager发送告警信息
- 然后,Alertmanager管理这些告警,包括进行重复数据删除,分组和路由,以及告警的静默和抑制
8.1.3 告警特性
- 去重
将多个相同的告警,去掉重复的告警,只保留不同的告警 - 分组 Grouping
分组机制可以将相似的告警信息合并成一个通知。
在某些情况下,比如由于系统宕机导致大量的告警被同时触发,在这种情况下分组机制可以将这些被触发的告警合并为一个告警通知,避免一次性接受大量的告警通知,而无法对问题进行快速定位。
告警分组,告警时间,以及告警的接受方式可以通过Alertmanager的配置文件进行配置。 - 抑制 Inhibition
系统中某个组件或服务故障,那些依赖于该组件或服务的其它组件或服务可能也会因此而触发告警,抑制便是避免类似的级联告警的一种特性,从而让用户能将精力集中于真正的故障所在
抑制可以避免当某种问题告警产生之后用户接收到大量由此问题导致的一系列的其它告警通知
抑制的关键作用在于,同时存在的两组告警条件中,其中一组告警如果生效,能使得另一组告警失效同样通过Alertmanager的配置文件进行设置 - 静默 Silent
静默提供了一个简单的机制可以快速根据标签在一定的时间对告警进行静默处理。
如果接收到的告警符合静默的配置,Alertmanager则不会发送告警通知。比如:通常在系统例行维护期间,需要激活告警系统的静默特性
静默设置可以在Alertmanager的Web页面上进行设置。 - 路由 Route
将不同的告警定制策略路由发送至不同的目标,比如:不同的接收人或接收媒介
8.2 二进制部署
https://github.com/prometheus/alertmanager/releases
1 | [root@mongo1 ~]# tar -xf alertmanager-0.33.1.linux-amd64.tar.gz -C /usr/local/ |
web界面

localhost:9093/metrics
8.3 prometheus告警规则
https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/
8.3.1 告警规则说明
警报规则可以实现基于Prometheus表达式语言定义警报条件,并将有关触发警报的通知发送到外部服务。 只要警报表达式在给定的时间点生成一个或多个动作元素,警报就被视为这些元素的标签集处于活动状态。
告警规则中使用的查询语句较为复杂时,可将其保存为记录规则,而后通过查询该记录规则生成的时间序列来参与比较,从而避免实时查询导致的较长时间延迟
警报规则在Prometheus中的基本配置方式与记录规则基本一致。
在Prometheus中一条告警规则主要由以下几部分组成:
- 告警名称:用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容
- 告警规则:告警规则实际上主要由PromQL进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警
在Prometheus中,还可以通过Group(告警组)对一组相关的告警进行统一定义。这些定义都是通过YAML文件来统一管理的
告警规则文件示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 groups:
- name: example
rules:
- alert: HighRequestLatency
expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
for: 10m
labels:
severity: warning
annotations:
summary: "Instance {{ $labels.instance }} down"
description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minutes."
#属性解析:
alert: #定制告警的动作名称
expr: #是一个布尔型的条件表达式,一般表示满足此条件时即为需要告警的异常状态
for: #条件表达式被触发后,一直持续满足该条件长达此处时长后才会告警,即发现满足expr表达式后,在告警前的等待时长,默认为0,此时间前为pending状态,之后为firing,此值应该大于抓取间隔时长,避免偶然性的故障
labels: ##指定告警规则的标签,若已添加,则每次告警都会覆盖前一次的标签值
labels.severity: #自定义的告警级别的标签
annotations: #自定义注释信息,注释信息中的变量需要从模板中或者系统中读取,最终体现在告警通知的信息中Prometheus 告警规则
告警规则
1 | [root@mongo1 rules]# cat prometheus_alert_rules.yml |
1 | [root@mongo1 rules]# promtool check rules /usr/local/prometheus/rules/prometheus_alert_rules.yml |
8.3.2 告警规则案例:邮件告警
alertmanager:
1 | [root@mongo1 alertmanager]# cat /usr/local/alertmanager/conf/alertmanager.yml |
prometheus.yml 配置alertmanager
1 | # Alertmanager configuration |


邮件列表,告警邮件恢复邮件

