【0】介紹
Prometheus提供了一種稱為PromQL(Prometheus查詢語言)的功能查詢語言,它使用戶可以實時選擇和匯總時間序列數據。
表達式的結果可以顯示為圖形,可以在Prometheus的表達式瀏覽器中顯示為表格數據,也可以由外部系統通過HTTP API使用。
【1】表達式的類型
【1.1】4大基本類型
- Instant vector(向量) -一組時間序列,每個時間序列包含一個樣本,所有樣本共享相同的時間戳(簡單理解:具體的采集指標的值)
- Range vector(向量)-一組時間序列,其中包含每個時間序列隨時間變化的一系列數據點(簡單理解:查看某個時間范圍的數據)
- Scalar(標量) - 一個簡單的數字浮點值(簡答理解:數字)
- String -一個簡單的字符串值;目前未使用
【1.2】Instant vector (即時向量選擇器)
本示例選擇所有具有 prometheus_http_requests_total 度量標准名稱的時間序列:
prometheus_http_requests_total
包含這么多呢
過在花括號({}
)后面加上逗號分隔的標簽匹配器列表,可以進一步過濾這些時間序列。
prometheus_http_requests_total{code="302",handler="/",instance="localhost:9090",job="prometheus"}
也可以:node_load1{job='agent_linux'} 是吧
【1.3】等於/不等於匹配符
=
:選擇與提供的字符串完全相同的標簽。!=
:選擇不等於提供的字符串的標簽。=~
:選擇與提供的字符串進行正則表達式匹配的標簽。!~
:選擇與提供的字符串不進行正則表達式匹配的標簽。
例如,此選擇所有http_requests_total
的時間序列staging
, testing
以及development
環境和HTTP比其他方法GET
。
http_requests_total{environment=~"staging|testing|development",method!="GET"}
向量選擇器必須指定一個名稱或至少一個與空字符串不匹配的標簽匹配器。以下表達式是非法的:
{job=~".*"} # Bad!
相反,這些表達式都是有效的,因為它們都具有與空標簽值不匹配的選擇器。
{job=~".+"} # Good!
{job=~".*",method="get"} # Good!
【1.4】range vector(范圍向量選擇器)
范圍向量文字的工作方式與即時向量文字相同,不同之處在於它們從當前即時中選擇了一系列樣本。從句法上講,范圍持續時間附加在[]
向量選擇器末尾的方括號()中,以指定應為每個結果范圍向量元素提取多遠的時間值。
持續時間指定為數字,緊隨其后的是以下單位之一:
s
-秒m
- 分鍾h
- 小時d
- 天w
-周y
-年
在此示例中,我們選擇所有時間序列在過去5分鍾內記錄的所有值,這些時間序列的度量標准名稱http_requests_total
和job
標簽設置為prometheus
:
http_requests_total{job="prometheus"}[5m]
【1.5】Offset modifier(偏移量修改器)
所述offset
改性劑可以改變時間為查詢中的個別時刻和范圍矢量偏移。
例如,以下表達式返回http_requests_total
相對於當前查詢評估時間的過去5分鍾的值 :
http_requests_total offset 5m
請注意,offset
修飾符始終需要立即跟隨選擇器,即以下內容將是正確的:
sum(http_requests_total{method="GET"} offset 5m) // GOOD.
雖然以下是不正確的:
sum(http_requests_total{method="GET"}) offset 5m // INVALID.
范圍向量的工作原理相同。這將返回http_requests_total
一周前的5分鍾費率 :
rate(http_requests_total[5m] offset 1w)
【1.6】子查詢
子查詢允許您針對給定的范圍和分辨率運行即時查詢。子查詢的結果是范圍向量。
句法: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
<resolution>
是可選的。默認值為全局評估間隔
PromQL支持以開頭的行注釋 # this is a comment
【2】二元運算
【2.1】二元算數運算
Prometheus中存在以下二進制算術運算符:
+
(加成)-
(減法)*
(乘法)/
(師)%
(取模)^
(冪/冪)
(1)標量和向量
【標量】:就是數字 【向量】:就是采集指標得到的值
官網描述:
(我的理解:就是兩個數字做操作,得到的也是一個數字)在兩個標量之間,其行為顯而易見:它們求值另一個標量,這是將運算符應用於兩個標量操作數的結果。
(我的理解:就是采集指標下值可能有很多個,如果做 * 2操作,那么所有值都要 * 2)在瞬時向量和標量之間,將運算符應用於向量中每個數據樣本的值。例如,如果時間序列瞬時向量乘以2,則結果是另一個向量,其中原始向量的每個樣本值都乘以2。
(我的理解:就是兩個采集指標下面均可能有多個值,如果相乘,那么就向左邊的指標一一匹配相乘,沒匹配到的就不顯示)在兩個即時向量之間,將二進制算術運算符應用於左側向量中的每個條目,並將其 應用於右側向量中的匹配元素。結果將傳播到結果向量中,並且分組標簽成為輸出標簽集。指標名稱已刪除。在右側向量中找不到匹配條目的條目不屬於結果。
【2.2】二元比較運算
在Prometheus系統中,比較二元操作符有:
==
等於!=
不等於>
大於<
小於>=
大於等於<=
小於等於
兩個數字之間:變成 bool 來做比較,結果返回 0 或者 1,即真 或者 假
數字和指標之間:把這個比較應用於指標中的每個值。
【2.3】二元邏輯運算
邏輯/集合二元操作符只能作用在即時向量, 包括:
and
交集or
並集unless
補集
並交補就不用說了吧。
vector1 and vector2
得到一個由vector1
元素組成的向量,其中vector2
中的元素具有完全匹配的標簽集。 其他元素被刪除。 度量標准名稱和值從左側向量轉移
vector1 or vector2
得到包含vector1
的所有原始元素(標簽集+值)的向量以及vector2
中vector1
中沒有匹配標簽集的所有元素。。
vector1 unless vector2
得到一個由vector1
元素組成的向量,其中vector2
中沒有元素,具有完全匹配的標簽集。 兩個向量中的所有匹配元素
【2.4】聚合操作符
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)
【2.5】二元運算符的優先級
以下列表顯示了Prometheus中二進制運算符的優先級,從最高到最低。
- ^
- *, /, %
- +, -
- ==, !=, <=, <, >=, >
- and, unless
- or
具有相同優先級的運算符是左關聯的。 例如,2 * 3%2
相當於(2 * 3)%2
。但是^
是右關聯的,因此2 ^ 3 ^ 2
相當於2 ^(3 ^ 2)
。
【3】常用函數
rate(node_network_receive_bytes_total[1m])
計算1分鍾內的平均值
increase(node_network_receive_bytes_total{device="eth0"}[1m])
計算1分鍾內的 第一個值和最后一個值 的差值
irate(http_requests_total{job="api-server"}[5m])
計算5分鍾內,最后的兩個值的差值
一些函數有默認的參數,例如:year(v=vector(time()) instant-vector)
。v是參數值,instant-vector是參數類型。vector(time())是默認值。
abs()
abs(v instant-vector)
返回輸入向量的所有樣本的絕對值。
absent()
absent(v instant-vector)
,如果賦值給它的向量具有樣本數據,則返回空向量;如果傳遞的瞬時向量參數沒有樣本數據,則返回不帶度量指標名稱且帶有標簽的樣本值為1的結果
當監控度量指標時,如果獲取到的樣本數據是空的, 使用absent方法對告警是非常有用的
absent(nonexistent{job="myjob"}) # => key: value = {job="myjob"}: 1
absent(nonexistent{job="myjob", instance=~".*"}) # => {job="myjob"} 1 so smart !
absent(sum(nonexistent{job="myjob"})) # => key:value {}: 0
ceil()
ceil(v instant-vector)
是一個向上舍入為最接近的整數。
changes()
changes(v range-vector)
輸入一個范圍向量, 返回這個范圍向量內每個樣本數據值變化的次數。
clamp_max()
clamp_max(v instant-vector, max scalar)
函數,輸入一個瞬時向量和最大值,樣本數據值若大於max,則改為max,否則不變
clamp_min()
clamp_min(v instant-vector)
函數,輸入一個瞬時向量和最大值,樣本數據值小於min,則改為min。否則不變
count_saclar()
count_scalar(v instant-vector)
函數, 輸入一個瞬時向量,返回key:value="scalar": 樣本個數。而count()
函數,輸入一個瞬時向量,返回key:value=向量:樣本個數,其中結果中的向量允許通過by
條件分組。
day_of_month()
day_of_month(v=vector(time()) instant-vector)
函數,返回被給定UTC時間所在月的第幾天。返回值范圍:1~31。
day_of_week()
day_of_week(v=vector(time()) instant-vector)
函數,返回被給定UTC時間所在周的第幾天。返回值范圍:0~6. 0表示星期天。
days_in_month()
days_in_month(v=vector(time()) instant-vector)
函數,返回當月一共有多少天。返回值范圍:28~31.
delta()
delta(v range-vector)
函數,計算一個范圍向量v的第一個元素和最后一個元素之間的差值。返回值:key:value=度量指標:差值
下面這個表達式例子,返回過去兩小時的CPU溫度差:
delta(cpu_temp_celsius{host="zeus"}[2h])
delta
函數返回值類型只能是gauges。
deriv()
deriv(v range-vector)
函數,計算一個范圍向量v中各個時間序列二階導數,使用簡單線性回歸
deriv
二階導數返回值類型只能是gauges。
drop_common_labels()
drop_common_labels(instant-vector)
函數,輸入一個瞬時向量,返回值是key:value=度量指標:樣本值,其中度量指標是去掉了具有相同標簽。 例如:http_requests_total{code="200", host="127.0.0.1:9090", method="get"} : 4, http_requests_total{code="200", host="127.0.0.1:9090", method="post"} : 5, 返回值: http_requests_total{method="get"} : 4, http_requests_total{code="200", method="post"} : 5
exp()
exp(v instant-vector)
函數,輸入一個瞬時向量, 返回各個樣本值的e指數值,即為e^N次方。特殊情況如下所示:
Exp(+inf) = +Inf Exp(NaN) = NaN
floor()
floor(v instant-vector)
函數,與ceil()
函數相反。 4.3 為 4 。
histogram_quantile()
histogram_quatile(φ float, b instant-vector)
函數計算b向量的φ-直方圖 (0 ≤ φ ≤ 1) 。參考中文文獻[https://www.howtoing.com/how-to-query-prometheus-on-ubuntu-14-04-part-2/]
holt_winters()
holt_winters(v range-vector, sf scalar, tf scalar)
函數基於范圍向量v,生成事件序列數據平滑值。平滑因子sf
越低, 對老數據越重要。趨勢因子tf
越高,越多的數據趨勢應該被重視。0< sf, tf <=1。 holt_winters
僅用於gauges
hour()
hour(v=vector(time()) instant-vector)
函數返回被給定UTC時間的當前第幾個小時,時間范圍:0~23。
idelta()
idelta(v range-vector)
函數,輸入一個范圍向量,返回key: value = 度量指標: 每最后兩個樣本值差值。
increase()
increase(v range-vector)
函數, 輸入一個范圍向量,返回:key:value = 度量指標:last值-first值,自動調整單調性,如:服務實例重啟,則計數器重置。與delta()
不同之處在於delta是求差值,而increase返回最后一個減第一個值,可為正為負。
下面的表達式例子,返回過去5分鍾,連續兩個時間序列數據樣本值的http請求增加值。
increase(http_requests_total{job="api-server"}[5m])
increase
的返回值類型只能是counters,主要作用是增加圖表和數據的可讀性,使用rate
記錄規則的使用率,以便持續跟蹤數據樣本值的變化。
irate
irate(v range-vector)
函數, 輸入:范圍向量,輸出:key: value = 度量指標: (last值-last前一個值)/時間戳差值。它是基於最后兩個數據點,自動調整單調性, 如:服務實例重啟,則計數器重置。
下面表達式針對范圍向量中的每個時間序列數據,返回兩個最新數據點過去5分鍾的HTTP請求速率。
irate(http_requests_total{job="api-server"}[5m])
irate
只能用於繪制快速移動的計數器。因為速率的簡單更改可以重置FOR子句,利用警報和緩慢移動的計數器,完全由罕見的尖峰組成的圖形很難閱讀。
label_replace()
對於v中的每個時間序列,label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)
將正則表達式與標簽值src_label匹配。如果匹配,則返回時間序列,標簽值dst_label被替換的擴展替換。$1替換為第一個匹配子組,$2替換為第二個等。如果正則表達式不匹配,則時間序列不會更改。
另一種更容易的理解是:label_replace
函數,輸入:瞬時向量,輸出:key: value = 度量指標: 值(要替換的內容:首先,針對src_label標簽,對該標簽值進行regex正則表達式匹配。如果不能匹配的度量指標,則不發生任何改變;否則,如果匹配,則把dst_label標簽的標簽紙替換為replacement 下面這個例子返回一個向量值a帶有foo
標簽:label_replace(up{job="api-server", serice="a:c"}, "foo", "$1", "service", "(.*):.*")
ln()
ln(v instance-vector)
計算瞬時向量v中所有樣本數據的自然對數。特殊例子:
ln(+Inf) = +Inf ln(0) = -Inf ln(x<0) = NaN ln(NaN) = NaN
log2()
log2(v instant-vector)
函數計算瞬時向量v中所有樣本數據的二進制對數。
log10()
log10(v instant-vector)
函數計算瞬時向量v中所有樣本數據的10進制對數。相當於ln()
minute()
minute(v=vector(time()) instant-vector)
函數返回給定UTC時間當前小時的第多少分鍾。結果范圍:0~59。
month()
month(v=vector(time()) instant-vector)
函數返回給定UTC時間當前屬於第幾個月,結果范圍:0~12。
predict_linear()
predict_linear(v range-vector, t scalar)
預測函數,輸入:范圍向量和從現在起t秒后,輸出:不帶有度量指標,只有標簽列表的結果值。
例如:predict_linear(http_requests_total{code="200",instance="120.77.65.193:9090",job="prometheus",method="get"}[5m], 5) 結果: {code="200",handler="query_range",instance="120.77.65.193:9090",job="prometheus",method="get"} 1 {code="200",handler="prometheus",instance="120.77.65.193:9090",job="prometheus",method="get"} 4283.449995397104 {code="200",handler="static",instance="120.77.65.193:9090",job="prometheus",method="get"} 22.99999999999999 {code="200",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 130.90381188596754 {code="200",handler="graph",instance="120.77.65.193:9090",job="prometheus",method="get"} 2 {code="200",handler="label_values",instance="120.77.65.193:9090",job="prometheus",method="get"} 2
rate()
rate(v range-vector)
函數, 輸入:范圍向量,輸出:key: value = 不帶有度量指標,且只有標簽列表:(last值-first值)/時間差s
rate(http_requests_total[5m]) 結果: {code="200",handler="label_values",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="query_range",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="prometheus",instance="120.77.65.193:9090",job="prometheus",method="get"} 0.2 {code="200",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0.003389830508474576 {code="422",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="static",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="graph",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="400",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0
rate()
函數返回值類型只能用counters, 當用圖表顯示增長緩慢的樣本數據時,這個函數是非常合適的。
注意:當rate函數和聚合方式聯合使用時,一般先使用rate函數,再使用聚合操作, 否則,當服務實例重啟后,rate無法檢測到counter重置。
resets()
resets()
函數, 輸入:一個范圍向量,輸出:key-value=沒有度量指標,且有標簽列表[在這個范圍向量中每個度量指標被重置的次數]。在兩個連續樣本數據值下降,也可以理解為counter被重置。 示例:
resets(http_requests_total[5m]) 結果: {code="200",handler="label_values",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="query_range",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="prometheus",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="422",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="static",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="200",handler="graph",instance="120.77.65.193:9090",job="prometheus",method="get"} 0 {code="400",handler="query",instance="120.77.65.193:9090",job="prometheus",method="get"} 0
resets只能和counters一起使用。
round()
round(v instant-vector, to_nearest 1= scalar)
函數,與ceil
和floor
函數類似,輸入:瞬時向量,輸出:指定整數級的四舍五入值, 如果不指定,則是1以內的四舍五入。
scalar()
scalar(v instant-vector)
函數, 輸入:瞬時向量,輸出:key: value = "scalar", 樣本值[如果度量指標樣本數量大於1或者等於0, 則樣本值為NaN, 否則,樣本值本身]
sort()
sort(v instant-vector)
函數,輸入:瞬時向量,輸出:key: value = 度量指標:樣本值[升序排列]
sort_desc()
sort(v instant-vector
函數,輸入:瞬時向量,輸出:key: value = 度量指標:樣本值[降序排列]
sqrt()
sqrt(v instant-vector)
函數,輸入:瞬時向量,輸出:key: value = 度量指標: 樣本值的平方根
time()
time()
函數,返回從1970-01-01到現在的秒數,注意:它不是直接返回當前時間,而是時間戳
vector()
vector(s scalar)
函數,返回:key: value= {}, 傳入參數值
year()
year(v=vector(time()) instant-vector)
, 返回年份。
_over_time()
下面的函數列表允許傳入一個范圍向量,返回一個帶有聚合的瞬時向量:
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)
: 范圍向量內每個度量指標的總體標准偏差。- `stdvar_over_time(range-vector): 范圍向量內每個度量指標的總體標准方差。
摘取來自Github 權侵刪!摘取來自Github 權侵刪!摘取來自Github 權侵刪!摘取來自Github 權侵刪!摘取來自Github 權侵刪!摘取來自Github 權侵刪!