简介
Prometheus 通过指标名称(metrics name)以及对应的一组标签(labelset)唯一
定义一条时间序列。指标名称反映了监控样本的基本标识,而 label 则在这个基本特征上为
采集到的数据提供了多种特征维度。用户可以基于这些特征维度过滤,聚合,统计从而产生
新的计算后的一条时间序列。PromQL 是 Prometheus 内置的数据查询语言,其提供对时
间序列数据丰富的查询,聚合以及逻辑运算能力的支持。并且被广泛应用在 Prometheus
的日常应用当中,包括对数据查询、可视化、告警处理当中
查询时间序列
语法
prometheus_http_requests_total
等同于
prometheus_http_requests_total{}
该表达式会返回指标名称为 prometheus_http_requests_total 的所有时间序列:
prometheus_http_requests_total{code=“200”,handler=“alerts”,instance=“localhost:9090”,j
ob=“prometheus”,method=“get”}= (20889@1518096812.326)
prometheus_http_requests_total{code=“200”,handler=“graph”,instance=“localhost:9090”,jo
b=“prometheus”,method=“get”}= (21287@1518096812.326)
理解
你看{}里头那么多键值对,如l{code=“200”,handler=“graph”,instance=“localhost:9090”,jo
b=“prometheus”,method=“get”}
那么{}就是搜所有
以此类推:
例如,如果我们只需要查询所有 prometheus_http_requests_total 时间序列中满足标
签 instance 为 localhost:9090 的时间 序列,则可以使用如下表达式:
prometheus_http_requests_total{instance=“localhost:9090”}
反之使用 instance!=“localhost:9090” 则可以排除这些时间序列:
prometheus_http_requests_total{instance!=“localhost:9090”}
其实就是在{}里面写你需要查询的条件
甚至还能通过正则
➢ PromQL还可以支持使用正则表达式作为匹配条件,多个表达式之间使用 | 进行分离:
⚫ 使用 label=~regx 表示选择那些标签符合正则表达式定义的时间序列;
⚫ 反之使用 label!~regx 进行排除;
例如,如果想查询多个环节下的时间序列序列可以使用如下表达式:
prometheus_http_requests_total{environment=~“staging|testing|development”,method!="GET
"}
排除用法
prometheus_http_requests_total{environment!~“staging|testing|development”,method!="GET
"}
范围查询
瞬时向量和区间向量
一句话,瞬时向量就是当前,区间向量就是一段时间
直接通过类似于 PromQL 表达式 httprequeststotal 查询时间序列时,返回值中只会
包含该时间序列中的最新的一个样本值,这样的返回结果我们称之为瞬时向量。而相应的这
样的表达式称之为__瞬时向量表达式。
而如果我们想过去一段时间范围内的样本数据时,我们则需要使用区间向量表达式。区
间向量表达式和瞬时向量表达式之间的差异在于在区间向量表达式中我们需要定义时间选
择的范围,时间范围通过时间范围选择器 [] 进行定义。 例如,通过以下表达式可以选择
最近 5 分钟内的所有样本数据:
prometheus_http_requests_total{}[5m]
通过区间向量表达式查询到的结果我们称为区间向量。 除了使用 m 表示分钟以外,
PromQL 的时间范围选择器支持其它时间单位:
⚫ s - 秒
⚫ m - 分钟
⚫ h - 小时
⚫ d - 天
⚫ w - 周
⚫ y - 年
而如果我们想查询,5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据呢? 这
个时候我们就可以使用位移操作,位移操作的关键字为 offset。 可以使用 offset 时间位移
操作:
prometheus_http_requests_total{} offset 5m
prometheus_http_requests_total{}[1d] offset 1d
聚合
函数和sql差不多,分组的时候其实把group by的语法简化成by而已
比如
查询系统所有 http 请求的总量
sum(prometheus_http_requests_total)
按照 mode 计算主机 CPU 的平均使用时间
avg(node_cpu_seconds_total) by (mode)
按照主机查询各个主机的 CPU 使用率
sum(sum(irate(node_cpu_seconds_total{mode!=‘idle’}[5m])) / sum(irate(node_cpu_
seconds_total [5m]))) by (instance)
标量和字符串、操作符
可以是一个数字
那么加减乘除不在话下
bool
特别要说一下的是bool!一般来说是用在过滤结果集里面
但是!!!如果你是需要返回一个bool值,那你就得这样
prometheus_http_requests_total > bool
1000
标量必须加 bool运算符
2 == bool 2 # 结果为 1
优先级
对于复杂类型的表达式,需要了解运算操作的运行优先级。例如,查询主机的 CPU 使
用率,可以使用表达式:
100 * (1 - avg (irate(node_cpu_seconds_total{mode=‘idle’}[5m])) by(job) )
其中irate是PromQL中的内置函数,用于计算区间向量中时间序列每秒的即时增长率。
在 PromQL 操作符中优先级由高到低依次为:
⚫ ^
⚫ *, /, %
⚫ +, -
⚫ ==, !=, <=, =, >
⚫ and, unless
⚫ or
表达式合法
首先,
所有的 PromQL 表达式都必须至少包含一个指标名称(例如 http_request_total),或者
一个不会匹配到空字符串的标签过滤器(例如{code=”200”})。
因此以下两种方式,均为合法的表达式:
prometheus_http_requests_total # 合法
prometheus_http_requests_total{} # 合法
{method=“get”} # 合法
而如下表达式,则不合法:
{job=~“.*”} # 不合法
还有一个看着好像没什么用,但是突然感觉写代码好像还不错的-》
同时,除了使用 {label=value} 的形式以外,我们还可以使用内置的 name 标签
来指定监控指标名称:
{name=~“prometheus_http_requests_total”} # 合法
{name=~“node_disk_bytes_read|node_disk_bytes_written”} # 合法