Prometheus 查詢語(yǔ)言

[TOC]

Prometheus 查詢語(yǔ)言

PromQL(Prometheus Query Language)是 Prometheus 自己開(kāi)發(fā)的表達(dá)式語(yǔ)言,語(yǔ)言表現(xiàn)力很豐富,內(nèi)置函數(shù)也很多。使用它可以對(duì)時(shí)序數(shù)據(jù)進(jìn)行篩選和聚合。

1. PromQL 語(yǔ)法

1.1 數(shù)據(jù)類型

PromQL 表達(dá)式計(jì)算出來(lái)的值有以下幾種類型:

  • 瞬時(shí)向量 (Instant vector): 一組時(shí)序,每個(gè)時(shí)序只有一個(gè)采樣值
  • 區(qū)間向量 (Range vector): 一組時(shí)序,每個(gè)時(shí)序包含一段時(shí)間內(nèi)的多個(gè)采樣值
  • 標(biāo)量數(shù)據(jù) (Scalar): 一個(gè)浮點(diǎn)數(shù)
  • 字符串 (String): 一個(gè)字符串,暫時(shí)未用

1.2 時(shí)序選擇器

1.2.1 瞬時(shí)向量選擇器

瞬時(shí)向量選擇器用來(lái)選擇一組時(shí)序在某個(gè)采樣點(diǎn)的采樣值。

最簡(jiǎn)單的情況就是指定一個(gè)度量指標(biāo),選擇出所有屬于該度量指標(biāo)的時(shí)序的當(dāng)前采樣值。比如下面的表達(dá)式:

http_requests_total

可以通過(guò)在后面添加用大括號(hào)包圍起來(lái)的一組標(biāo)簽鍵值對(duì)來(lái)對(duì)時(shí)序進(jìn)行過(guò)濾。比如下面的表達(dá)式篩選出了 jobprometheus,并且 groupcanary 的時(shí)序:

http_requests_total{job="prometheus", group="canary"}

匹配標(biāo)簽值時(shí)可以是等于,也可以使用正則表達(dá)式??偣灿邢旅鎺追N匹配操作符:

  • =:完全相等
  • !=: 不相等
  • =~: 正則表達(dá)式匹配
  • !~: 正則表達(dá)式不匹配

下面的表達(dá)式篩選出了 environment 為 staging 或 testing 或 development,并且 method 不是 GET 的時(shí)序:

http_requests_total{environment=~"staging|testing|development",method!="GET"}

度量指標(biāo)名可以使用內(nèi)部標(biāo)簽 __name__ 來(lái)匹配,表達(dá)式 http_requests_total 也可以寫(xiě)成 {__name__="http_requests_total"}。表達(dá)式 {__name__=~"job:.*"} 匹配所有度量指標(biāo)名稱以 job: 打頭的時(shí)序。

1.2.2 區(qū)間向量選擇器

區(qū)間向量選擇器類似于瞬時(shí)向量選擇器,不同的是它選擇的是過(guò)去一段時(shí)間的采樣值??梢酝ㄟ^(guò)在瞬時(shí)向量選擇器后面添加包含在 [] 里的時(shí)長(zhǎng)來(lái)得到區(qū)間向量選擇器。比如下面的表達(dá)式選出了所有度量指標(biāo)為 http_requests_totaljobprometheus 的時(shí)序在過(guò)去 5 分鐘的采樣值。

http_requests_total{job="prometheus"}[5m]

說(shuō)明:時(shí)長(zhǎng)的單位可以是下面幾種之一:

  • s:seconds
  • m:minutes
  • h:hours
  • d:days
  • w:weeks
  • y:years
1.2.3 偏移修飾器

前面介紹的選擇器默認(rèn)都是以當(dāng)前時(shí)間為基準(zhǔn)時(shí)間,偏移修飾器用來(lái)調(diào)整基準(zhǔn)時(shí)間,使其往前偏移一段時(shí)間。偏移修飾器緊跟在選擇器后面,使用 offset 來(lái)指定要偏移的量。比如下面的表達(dá)式選擇度量名稱為 http_requests_total 的所有時(shí)序在 5 分鐘前的采樣值。

http_requests_total offset 5m

下面的表達(dá)式選擇 http_requests_total 度量指標(biāo)在 1 周前的這個(gè)時(shí)間點(diǎn)過(guò)去 5 分鐘的采樣值。

http_requests_total[5m] offset 1w

2. PromQL 操作符

2.1 二元操作符

PromQL 的二元操作符支持基本的邏輯和算術(shù)運(yùn)算,包含算術(shù)類比較類邏輯類三大類。

2.1.1 算術(shù)類二元操作符

算術(shù)類二元操作符有以下幾種:

  • +:加
  • -:減
  • *:乘
  • /:除
  • %:求余
  • ^:乘方

算術(shù)類二元操作符可以使用在標(biāo)量與標(biāo)量、向量與標(biāo)量,以及向量與向量之間。

二元操作符上下文里的向量特指瞬時(shí)向量,不包括區(qū)間向量。

  • 標(biāo)量與標(biāo)量之間,結(jié)果很明顯,跟通常的算術(shù)運(yùn)算一致。
  • 向量與標(biāo)量之間,相當(dāng)于把標(biāo)量跟向量里的每一個(gè)標(biāo)量進(jìn)行運(yùn)算,這些計(jì)算結(jié)果組成了一個(gè)新的向量。
  • 向量與向量之間,會(huì)稍微麻煩一些。運(yùn)算的時(shí)候首先會(huì)為左邊向量里的每一個(gè)元素在右邊向量里去尋找一個(gè)匹配元素(匹配規(guī)則后面會(huì)講),然后對(duì)這兩個(gè)匹配元素執(zhí)行計(jì)算,這樣每對(duì)匹配元素的計(jì)算結(jié)果組成了一個(gè)新的向量。如果沒(méi)有找到匹配元素,則該元素丟棄。
2.1.2 比較類二元操作符

比較類二元操作符有以下幾種:

  • == (equal)
  • != (not-equal)
  • > (greater-than)
  • < (less-than)
  • >= (greater-or-equal)
  • <= (less-or-equal)

比較類二元操作符同樣可以使用在標(biāo)量與標(biāo)量、向量與標(biāo)量,以及向量與向量之間。默認(rèn)執(zhí)行的是過(guò)濾,也就是保留值。

也可以通過(guò)在運(yùn)算符后面跟 bool 修飾符來(lái)使得返回值 0 和 1,而不是過(guò)濾。

  • 標(biāo)量與標(biāo)量之間,必須跟 bool 修飾符,因此結(jié)果只可能是 0(false) 或 1(true)。
  • 向量與標(biāo)量之間,相當(dāng)于把向量里的每一個(gè)標(biāo)量跟標(biāo)量進(jìn)行比較,結(jié)果為真則保留,否則丟棄。如果后面跟了 bool 修飾符,則結(jié)果分別為 1 和 0。
  • 向量與向量之間,運(yùn)算過(guò)程類似于算術(shù)類操作符,只不過(guò)如果比較結(jié)果為真則保留左邊的值(包括度量指標(biāo)和標(biāo)簽這些屬性),否則丟棄,沒(méi)找到匹配也是丟棄。如果后面跟了 bool 修飾符,則保留和丟棄時(shí)結(jié)果相應(yīng)為 1 和 0。
2.1.3 邏輯類二元操作符

邏輯操作符僅用于向量與向量之間。

  • and:交集
  • or:合集
  • unless:補(bǔ)集

具體運(yùn)算規(guī)則如下:

  • vector1 and vector2 的結(jié)果由在 vector2 里有匹配(標(biāo)簽鍵值對(duì)組合相同)元素的 vector1 里的元素組成。
  • vector1 or vector2 的結(jié)果由所有 vector1 里的元素加上在 vector1 里沒(méi)有匹配(標(biāo)簽鍵值對(duì)組合相同)元素的 vector2 里的元素組成。
  • vector1 unless vector2 的結(jié)果由在 vector2 里沒(méi)有匹配(標(biāo)簽鍵值對(duì)組合相同)元素的 vector1 里的元素組成。
2.1.4 二元操作符優(yōu)先級(jí)

PromQL 的各類二元操作符運(yùn)算優(yōu)先級(jí)如下:

  1. ^
  2. *, /, %
  3. +, -
  4. ==, !=, <=, <, >=, >
  5. and, unless
  6. or

2.2 向量匹配

前面算術(shù)類和比較類操作符都需要在向量之間進(jìn)行匹配。共有兩種匹配類型,one-to-onemany-to-one / one-to-many。

2.2.1 One-to-one 向量匹配

這種匹配模式下,兩邊向量里的元素如果其標(biāo)簽鍵值對(duì)組合相同則為匹配,并且只會(huì)有一個(gè)匹配元素??梢允褂?ignoring 關(guān)鍵詞來(lái)忽略不參與匹配的標(biāo)簽,或者使用 on 關(guān)鍵詞來(lái)指定要參與匹配的標(biāo)簽。語(yǔ)法如下:

<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>

比如對(duì)于下面的輸入:

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="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21

method:http_requests:rate5m{method="get"}  600
method:http_requests:rate5m{method="del"}  34
method:http_requests:rate5m{method="post"} 120

執(zhí)行下面的查詢:

method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m

得到的結(jié)果為:

{method="get"}  0.04            //  24 / 600
{method="post"} 0.05            //   6 / 120

也就是每一種 method 里 code 為 500 的請(qǐng)求數(shù)占總數(shù)的百分比。由于 method 為 put 和 del 的沒(méi)有匹配元素所以沒(méi)有出現(xiàn)在結(jié)果里。

2.2.2 Many-to-one / one-to-many 向量匹配

這種匹配模式下,某一邊會(huì)有多個(gè)元素跟另一邊的元素匹配。這時(shí)就需要使用 group_leftgroup_right 組修飾符來(lái)指明哪邊匹配元素較多,左邊多則用 group_left,右邊多則用 group_right。其語(yǔ)法如下:

<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>

組修飾符只適用于算術(shù)類和比較類操作符。

對(duì)于前面的輸入,執(zhí)行下面的查詢:

method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

將得到下面的結(jié)果:

{method="get", code="500"}  0.04            //  24 / 600
{method="get", code="404"}  0.05            //  30 / 600
{method="post", code="500"} 0.05            //   6 / 120
{method="post", code="404"} 0.175           //  21 / 120

也就是每種 method 的每種 code 錯(cuò)誤次數(shù)占每種 method 請(qǐng)求數(shù)的比例。這里匹配的時(shí)候 ignoring 了 code,才使得兩邊可以形成 Many-to-one 形式的匹配。由于左邊多,所以需要使用 group_left 來(lái)指明。

Many-to-one / one-to-many 過(guò)于高級(jí)和復(fù)雜,要盡量避免使用。很多時(shí)候通過(guò) ignoring 就可以解決問(wèn)題。

2.3 聚合操作符

PromQL 的聚合操作符用來(lái)將向量里的元素聚合得更少??偣灿邢旅孢@些聚合操作符:

  • sum:求和
  • min:最小值
  • max:最大值
  • avg:平均值
  • stddev:標(biāo)準(zhǔn)差
  • stdvar:方差
  • count:元素個(gè)數(shù)
  • count_values:等于某值的元素個(gè)數(shù)
  • bottomk:最小的 k 個(gè)元素
  • topk:最大的 k 個(gè)元素
  • quantile:分位數(shù)

聚合操作符語(yǔ)法如下:

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]

其中 without 用來(lái)指定不需要保留的標(biāo)簽(也就是這些標(biāo)簽的多個(gè)值會(huì)被聚合),而 by 正好相反,用來(lái)指定需要保留的標(biāo)簽(也就是按這些標(biāo)簽來(lái)聚合)。

下面來(lái)看幾個(gè)示例:

sum(http_requests_total) without (instance)

http_requests_total 度量指標(biāo)帶有 application、instance 和 group 三個(gè)標(biāo)簽。上面的表達(dá)式會(huì)得到每個(gè) application 的每個(gè) group 在所有 instance 上的請(qǐng)求總數(shù)。效果等同于下面的表達(dá)式:

sum(http_requests_total) by (application, group)

下面的表達(dá)式可以得到所有 application 的所有 group 的所有 instance 的請(qǐng)求總數(shù)。

sum(http_requests_total)

3. 函數(shù)

Prometheus 內(nèi)置了一些函數(shù)來(lái)輔助計(jì)算,下面介紹一些典型的。

  • abs():絕對(duì)值
  • sqrt():平方根
  • exp():指數(shù)計(jì)算
  • ln():自然對(duì)數(shù)
  • ceil():向上取整
  • floor():向下取整
  • round():四舍五入取整
  • delta():計(jì)算區(qū)間向量里每一個(gè)時(shí)序第一個(gè)和最后一個(gè)的差值
  • sort():排序
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容