本文来自Prometheus官网手册1、2、3 和 Prometheus简介1、2、3
web
Prometheus的查询语言支持基本的逻辑运算和算术运算。对于两个瞬时向量, 匹配行为能够被改变。正则表达式
在Prometheus支持下面的二元算术操做符:api
+
加法-
减法*
乘法/
除法%
模^
幂等二元运算操做符定义在scalar/scalar(标量/标量)
、vector/scalar(向量/标量)
、和vector/vector(向量/向量)
之间。浏览器
在Prometheus系统中,比较二元操做符有:app
==
等于!=
不等于>
大于<
小于>=
大于等于<=
小于等于比较二元操做符定义在scalar/scalar(标量/标量)
、vector/scalar(向量/标量)
,和vector/vector(向量/向量)
。默认状况下过滤。 能够经过在运算符以后提供bool
来修改它们的行为,这将为值返回0
或1
而不是过滤。less
bool
修饰符,而且这些运算符会产生另外一个标量,即0
(假)或1
(真),具体取决于比较结果。bool
修饰符,则将被删除的向量元素的值为0
,而将保留的向量元素的值为1。bool
修饰符,则已经删除的向量元素的值为0
,而保留的向量元素的值为1
,左侧标签值为1
。如:ide
3 > 2 # 报错 "comparisons between scalars must use BOOL modifier" 3 > bool 2 # 返回 scalar 1 1 > bool 2
逻辑/集合二元操做符只能做用在即时向量, 包括:函数
and
交集or
并集unless
补集vector1 and vector2:
获得一个由vector1
元素组成的向量,其中vector2
中的元素具备彻底匹配的标签集,其余元素被删除。post
vector1 or vector2:
获得包含vector1
的全部原始元素(标签集+值)的向量以及vector2
中vector1
中没有匹配标签集的全部元素。ui
vector1 unless vector2:
获得一个由vector1
元素组成的向量,其中vector2
中没有元素,具备彻底匹配的标签集。 两个向量中的全部匹配元素都被删除。
向量之间的操做尝试在左侧的每一个条目的右侧向量中找到匹配元素。 匹配行为有两种基本类型:一对一和多对一/一对多。
vector1<operator>vector2
以后的操做。 若是两个条目具备彻底相同的标签集和相应的值,则它们匹配。 忽略关键字容许在匹配时忽略某些标签,而on
关键字容许将所考虑的标签集减小到提供的列表:
[vector expr] [bin-op] ignoring([label list]) [vector expr]
[vector expr] [bin-op] on([lable list]) [vector expr]
例如样本数据:
method_code:http_errors:rate5m{method="get", code="500"} 24 method_code:http_errors:rate5m{method="get", code="404"} 30 method_code:http_errors:rate5m{method="put", code="501"} 3 method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600 method:http_requests:rate5m{method="delete"} 34 method:http_requests:rate5m{method="post"} 120
查询例子:
method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
ignoring(code)
就没有匹配,由于度量标准不共享同一组标签。 方法put
和del
的条目没有匹配,而且不会显示在结果中:
{method="get"} 0.04 // 24 / 600 {method="post"} 0.05 // 6 / 120
多对一和一对多匹配指的是“一”侧的每一个向量元素能够与“多”侧的多个元素匹配的状况。 必须使用group_left
或group_right
修饰符明确请求,其中left/right
肯定哪一个向量具备更高的基数。
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
随组修饰符提供的标签列表包含来自“一”侧的其余标签,以包含在结果度量标准中。 对于标签,只能出如今其中一个列表中。 每次结果向量的序列必须是惟一可识别的。
分组修饰符只能用于比较和算术。 默认状况下,操做as和除非和或操做与右向量中的全部可能条目匹配。示例查询:
method_code:http_errors:rate5m / ignoring(code) group_left
method:http_requests:rate5m
在这种状况下,左向量每一个method
标签值包含多个条目。 所以,咱们使用group_left
代表这一点。 右侧的元素如今与多个元素匹配,左侧具备相同的method
标签:
{method="get", code="500"} 0.04 // 24 /600 {method="get", code="404"} 0.05 // 30 /600 {method="post", code="500"} 0.05 // 6 /600 {method="post", code="404"} 0.175 // 21 /600
多对一和一对多匹配是高级用例,应该仔细考虑。 一般正确使用忽略ignoring(<labels>)
可提供所需的结果。
Prometheus支持如下内置聚合运算符,这些运算符可用于聚合单个即时向量的元素,从而生成具备聚合值的较少元素的新向量:
sum
(在维度上求和)max
(在维度上求最大值)min
(在维度上求最小值)avg
(在维度上求平均值)stddev
(求标准差)stdvar
(求方差)count
(统计向量元素的个数)count_values
(统计相同数据值的元素数量)bottomk
(样本值第k个最小值)topk
(样本值第k个最大值)quantile
(统计分位数)这些运算符能够用于聚合全部标签维度,也能够经过包含without
或by
子句来保留不一样的维度。
<aggr-op>([parameter,] <vector expr>) [without | by (<label list>)] [keep_common]
parameter
仅用于count_values
,quantile
,topk
和bottomk
。不从结果向量中删除列出的标签,而全部其余标签都保留输出。 by
相反并删除未在by
子句中列出的标签,即便它们的标签值在向量的全部元素之间是相同的。
count_values
输出每一个惟同样本值的一个时间序列。每一个系列都有一个额外的标签。该标签的名称由聚合参数给出,标签值是惟一的样本值。每一个时间序列的值是样本值存在的次数。
topk
和bottomk
与其余聚合器的不一样之处在于,输入样本的子集(包括原始标签)在结果向量中返回。 by
和without
仅用于存储输入向量。例:
若是度量标准http_requests_total
具备按应用程序,实例和组标签扇出的时间序列,咱们能够经过如下方式计算每一个应用程序和组在全部实例上看到的HTTP请求总数:
sum(http_requests_total) without (instance)
等价于:
sum(http_requests_total)
要计算运行每一个构建版本的二进制文件的数量,咱们能够编写:
count_values("version", build_version)
要在全部实例中获取5个最大的HTTP请求计数,咱们能够编写:
topk(5, http_requests_total)
如下列表显示了Prometheus中二进制运算符的优先级,从最高到最低。
具备相同优先级的运算符是左关联的。 例如,2 * 3%2
至关于(2 * 3)%2
。可是^
是右关联的,所以2 ^ 3 ^ 2
至关于2 ^(3 ^ 2)
。
year(v=vector(time()) instant-vector)
。意思是有一个参数v
是一个瞬时向量,若是没有提供,它将默认为表达式vector(time())
的值。
abs(v instant-vector)
返回输入向量,全部样本值都转换为其绝对值。
absent(v instant-vector)
若是传递给它的向量具备任何元素,则返回空向量;若是传递给它的向量没有元素,则返回值为1的1元素向量。这对于在给定度量标准名称和标签组合不存在时间序列时发出警报很是有用。
absent(nonexistent{job="myjob"}) # => {job="myjob"} absent(nonexistent{job="myjob", instance=~".*"}) # => {job="myjob"} absent(sum(nonexistent{job="myjob"})) # => {}
在第二个例子中,absent()
试图从输入向量中导出1元素输出向量的标签。
ceil(v instant-vector)
将v
中全部元素的样本值舍入到最接近的整数。
对于每一个输入时间序列,changes(v range-vector)将其值在提供的时间范围内变化的次数做为即时向量返回。
clamp_max(v instant-vector, max scalar) 将v中全部元素的样本值设为最大。
clamp_min(v instant-vector, min scalar)将
v
中全部元素的样本值设为最小。
day_of_month(v=vector(time()) instant-vector)
返回UTC中每一个给定时间的月中的某天。 返回值为1到31。
day_of_week(v=vector(time()) instant-vector)
返回UTC中每一个给定时间的星期几。 返回值为0到6,其中0表示星期日等。
days_in_month(v=vector(time()) instant-vector)
返回UTC中每一个给定时间的月中天数。 返回值为28到31。
delta(v range-vector)
计算范围向量v
中每一个时间系列元素的第一个和最后一个值之间的差值,返回具备给定增量和等效标签的即时向量。 如下示例表达式返回如今和2小时以前CPU温度的差别:
delta(cpu_temp_celsius{host="zeus"}[2h])
delta
应仅用于gauges
deriv(v range-vector)
函数,计算一个范围向量v中各个时间序列二阶导数,使用简单线性回归
deriv
应仅用于gauges。
exp(v instant-vector)
计算v
中全部元素的指数函数:
Exp(+inf) = +Inf
Exp(NaN) = NaN
floor(v instant-vector)
将v
中全部元素的样本值舍入为最接近的整数。。
histogram_quatile(φ float, b instant-vector)
计算b
向量的φ-直方图 (0 ≤ φ ≤ 1) 。(有关φ-分位数的详细解释和直方图度量类型的使用,请参见直方图和摘要。)b
中的样本是每一个桶中的观察计数。 每一个样本必须具备标签le
,其中标签值表示桶的包含上限。 (没有这种标签的样本会被忽略。)直方图度量标准类型自动提供带有_bucket
后缀和相应标签的时间序列。使用rate()
函数指定分位数计算的时间窗口。
示例:直方图度量标准称为http_request_duration_seconds
。 要计算过去10m内请求持续时间的第90个百分位数,请使用如下表达式:
histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[10m]))
http_request_duration_seconds
中为每一个标签组合计算分位数。 要聚合,请在rate()
函数周围使用sum()
聚合器。 因为histogram_quantile()
须要le
标签,所以必须将其包含在by
子句中。 如下表达式按做业聚合第90个百分点:
histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (job, le))
要聚合全部内容,请仅指定le
标签:
histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (le))
histogram_quantile()
函数经过假设桶内的线性分布来插值分位数值。 最高桶必须具备+Inf
的上限。 (不然,返回NaN
。)若是分位数位于最高桶中,则返回第二个最高桶的上限。 若是该桶的上限大于0,则假设最低桶的下限为0.在这种状况下,在该桶内应用一般的线性插值。 不然,对于位于最低桶中的分位数,返回最低桶的上限。
若是b
包含少于两个桶,则返回NaN
。 对于φ<0
,返回-Inf
。 对于φ> 1
,返回+Inf
。
holt_winters(v range-vector, sf scalar, tf scalar)
根据v
中的范围产生时间序列的平滑值。平滑因子sf
越低,对旧数据的重要性越高。 趋势因子tf
越高,则考虑的数据趋势越多。 sf
和tf
都必须介于0和1之间。
holt_winters
只能用于gauges。
hour(v=vector(time()) instant-vector)
返回UTC中每一个给定时间的一天中的小时。 返回值为0到23。
idelta(v range-vector)
计算范围向量v
中最后两个样本之间的差别,返回具备给定增量和等效标签的即时向量。
idelta
只能用于gauges。
increase(v range-vector)
计算范围向量中时间序列的增量。 单调性中断(例如因为目标重启而致使的计数器重置)会自动调整。 增长外推以覆盖范围向量选择器中指定的全时间范围,所以即便计数器仅以整数增量增长,也能够得到非整数结果。
如下示例表达式返回范围向量中每一个时间系列在过去5分钟内测量的HTTP请求数:
increase(http_requests_total{job="api-server"}[5m])
increase
只能与counter
一块儿使用。 它是rate(v)
以指定时间范围窗口下的秒数,应该主要用于人类可读性。 在记录规则中使用rate
,以便每秒一致地跟踪增加率。
irate(v range-vector)
计算范围向量中时间序列的每秒即时增加率。 这基于最后两个数据点。 单调性中断(例如因为目标重启而致使的计数器重置)会自动调整。
如下示例表达式返回范围向量中每一个时间序列的两个最新数据点的最多5分钟的HTTP请求的每秒速率:
irate(http_requests_total{job="api-server"}[5m])
只应在绘制易失性快速移动计数器时使用irate
。 警报和缓慢移动计数器的使用率,由于速率的简短更改能够重置FOR
子句,而且难以阅读彻底由稀有峰值组成的图形。
注意,当将irate()
与聚合运算符(例如sum()
)或随时间聚合的函数(任何以_over_time
结尾的函数)组合时,请始终首先采用irate()
,而后进行聚合。 不然,当目标从新启动时,irate()
没法检测计数器重置。
对于v
中的每一个时间序列,label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)
使用separator
链接全部src_labels
的全部值,并返回包含链接的标签dst_label
的时间序列 值。 此函数中能够有任意数量的src_labels
。
此示例将返回一个向量,每一个时间序列都有一个foo
标签,其中添加了值a,b,c
:
label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")
对于v
中的每一个时间序列,label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)
将正则表达式正则表达式与标签src_label
相匹配。 若是匹配,则返回时间序列,标签dst_label
替换为替换扩展。 $1
替换为第一个匹配的子组,$2
替换为第二个等。若是正则表达式不匹配,则返回时间序列不变。
此示例将返回一个向量,每一个时间序列都有一个foo
标签,其值为a
:
label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.):.")
ln(v instance-vector)
计算v
中全部元素的天然对数。特殊状况是:
ln(+Inf) = +Inf ln(0) = -Inf ln(x<0) = NaN ln(NaN) = NaN
log2(v instant-vector)
计算v
中全部元素的二进制对数。特殊状况等同于ln
中的特殊状况。
log10(v instant-vector)
计算v
中全部元素的10进制对数。特殊状况等同于ln
中的特殊状况。
minute(v=vector(time()) instant-vector)
以UTC为单位返回每一个给定时间的分钟。 返回值为0到59。
month(v=vector(time()) instant-vector)
返回UTC中每一个给定时间的一年中的月份。 返回值为1到12,其中1表示1月等。
predict_linear(v range-vector, t scalar)
根据范围向量v
使用线性回归预测从如今起t秒的时间序列值。
predict_linear
只能与gauges一块儿使用。
rate(v range-vector)
计算范围向量中时间序列的每秒平均增加率。 单调性中断(例如因为目标重启而致使的计数器重置)会自动调整。 此外,计算推断到时间范围的末端,容许错过刮擦或刮擦循环与范围的时间段的不完美对齐。
如下示例表达式返回范围向量中每一个时间系列在过去5分钟内测量的每秒HTTP请求率:
rate(http_requests_total{job="api-server"}[5m])
rate
应仅用于计数器。 它最适用于警报和缓慢移动计数器的图形。
注意,当将rate()
与聚合运算符(例如sum()
)或随时间聚合的函数(任何以_over_time
结尾的函数)组合时,始终首先采用rate()
,而后聚合。 不然,当目标从新启动时,rate()
没法检测计数器重置。
对于每一个时序数据,resets()
在所提供的时间范围内返回计数器重置次数做为即时向量。 两个连续样本之间的值的任何减小都被解释为计数器重置。
resets()
只能与counter一块儿使用。
round(v instant-vector, to_nearest 1= scalar)
将v
中全部元素的样本值舍入为最接近的整数。 经过四舍五入解决关系。 可选的to_nearest
参数容许指定样本值应舍入的最近倍数。 这个倍数也多是一个分数。
给定单元素输入向量,scalar(v instant-vector)
将该单个元素的样本值做为标量返回。 若是输入向量不具备刚好一个元素,则scalar
将返回NaN
。
sort(v instant-vector)
返回按其样本值排序的向量元素,按升序排列。
sort(v instant-vector
和sort
相同,但按降序排序。
sqrt(v instant-vector)
计算v
中全部元素的平方根。
time()
返回自1970年1月1日UTC以来的秒数。 请注意,这实际上并不返回当前时间,而是返回计算表达式的时间。
timestamp()
timestamp(v instant-vector)
返回给定向量的每一个样本的时间戳,做为自1970年1月1日UTC以来的秒数。
此功能已添加到Prometheus 2.0中
vector(s scalar)
将标量s
做为没有标签的向量返回。
year(v=vector(time()) instant-vector)
以UTC格式返回每一个给定时间的年份。
如下函数容许聚合给定范围向量的每一个系列随时间的变化并返回具备每系列聚合结果的即时向量:
avg_over_time(range-vector)
: 范围向量内每一个度量指标的平均值。min_over_time(range-vector)
: 范围向量内每一个度量指标的最小值。max_over_time(range-vector)
: 范围向量内每一个度量指标的最大值。sum_over_time(range-vector)
: 范围向量内每一个度量指标的求和值。count_over_time(range-vector)
: 范围向量内每一个度量指标的样本数据个数。quantile_over_time(scalar, range-vector)
: 范围向量内每一个度量指标的样本数据值分位数,φ-quantile (0 ≤ φ ≤ 1)stddev_over_time(range-vector)
: 范围向量内每一个度量指标的整体标准误差。请注意,即便值在整个时间间隔内的间隔不均匀,指定时间间隔内的全部值在聚合中都具备相同的权重。
使用度量标准http_requests_total
返回全部时间序列:
http_requests_total
使用度量标准http_requests_total
以及给定的job
和handler
标签返回全部时间系列:
http_requests_total{job="apiserver", handler="/api/comments"}
返回相同向量的整个时间范围(在本例中为5分钟),使其成为范围向量:
http_requests_total{job="apiserver", handler="/api/comments"}[5m]
请注意,致使范围向量的表达式不能直接绘制,而是在表达式浏览器的表格("Console")视图中查看。
使用正则表达式,您只能为名称与特定模式匹配的做业选择时间序列,在本例中为全部以server
结尾的做业。 请注意,这会进行子字符串匹配,而不是完整的字符串匹配:
http_requests_total{job=~"server$"}
要选择除4xx以外的全部HTTP状态代码,您能够运行:
http_requests_total{status!~"^4..$"}
http_requests_total
指标率,分辨率为1分钟:
rate(http_requests_total[5m])[30m:1m]
这是嵌套子查询的示例。 deri
函数的子查询使用默认分辨率。 请注意,没必要要地使用子查询是不明智的。
max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:])
使用http_requests_total
指标名称返回全部时间序列的每秒速率,在过去5分钟内测量:
rate(http_requests_total[5m])
http_requests_total
时间序列都有标签job
(按做业名称扇出)和instance
(按做业实例扇出),咱们可能想要总结全部实例的速率,所以咱们获得的输出时间序列更少,但仍然 保留job
维度
sum(rate(http_requests_total)[5m]) by (job)
(instance_memory_limit_byte - instant_memory_usage_bytes) / 1024 / 1024
相同的表达式,但由应用程序总结,能够这样写:
sum( instance_memory_limit_bytes - instance_memory_usage_bytes) by (app, proc) / 1024 / 1024
若是相同的虚构集群调度程序为每一个实例公开了以下所示的CPU使用率指标:
instance_cpu_time_ns{app="lion", pro="web", rev="34d0f99", env="prod", job="cluster-manager"} instance_cpu_time_ns{app="elephant", proc="worker", rev="34d0f99", env="prod", job="cluster-manager"} instance_cpu_time_ns{app="turtle", proc="api", rev="4d3a513", env="prod", job="cluster-manager"} ...
咱们能够按应用程序(app
)和进程类型(proc
)分组排名前3位的CPU用户:
topk(3, sum(rate(instance_cpu_time_ns[5m])) by(app, proc))
假设此度量标准包含每一个运行实例的一个时间系列,您能够计算每一个应用程序运行实例的数量,以下所示:
count(instance_cpu_time_ns) by (app)