1. 程式人生 > >你需要精通一種監控-初識PromQL

你需要精通一種監控-初識PromQL

PromQL是Prometheus內建的資料查詢語言,其提供對時間序列資料豐富的查詢,聚合以及邏輯運算能力的支援。並且被廣泛應用在Prometheus的日常應用當中,包括對資料查詢、視覺化、告警處理當中。可以這麼說,PromQL是Prometheus所有應用場景的基礎,理解和掌握PromQL是Prometheus入門的第一課。

查詢時間序列

當Prometheus通過Exporter採集到相應的監控指標樣本資料後,我們就可以通過PromQL對監控樣本資料進行查詢。

當我們直接使用監控指標名稱查詢時,可以查詢該指標下的所有時間序列。如:

http_requests_total

等同於:

http_requests_total{}

該表示式會返回指標名稱為http_requests_total的所有時間序列:

http_requests_total{code="200",handler="alerts",instance="localhost:9090",job="prometheus",method="get"}=([email protected])
http_requests_total{code="200",handler="graph",instance="localhost:9090",job="prometheus",method="get"}=([email protected])

PromQL還支援使用者根據時間序列的標籤匹配模式來對時間序列進行過濾,目前主要支援兩種匹配模式:完全匹配和正則匹配。

PromQL支援使用=!=兩種完全匹配模式:

  • 通過使用label=value可以選擇那些標籤滿足表示式定義的時間序列;

  • 反之使用label!=value則可以根據標籤匹配排除時間序列;

例如,如果我們只需要查詢所有http_requests_total時間序列中滿足標籤instance為localhost:9090的時間序列,則可以使用如下表達式:

http_requests_total{instance="localhost:9090"}

反之使用instance!="localhost:9090"

則可以排除這些時間序列:

http_requests_total{instance!="localhost:9090"}

除了使用完全匹配的方式對時間序列進行過濾以外,PromQL還可以支援使用正則表示式作為匹配條件,多個表示式之間使用|進行分離:

  • 使用label=~regx表示選擇那些標籤符合正則表示式定義的時間序列;

  • 反之使用label!~regx進行排除;

例如,如果想查詢多個環節下的時間序列序列可以使用如下表達式:

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

範圍查詢

直接通過類似於PromQL表示式httprequeststotal查詢時間序列時,返回值中只會包含該時間序列中的最新的一個樣本值,這樣的返回結果我們稱之為瞬時向量。而相應的這樣的表示式稱之為__瞬時向量表示式

而如果我們想過去一段時間範圍內的樣本資料時,我們則需要使用區間向量表示式。區間向量表示式和瞬時向量表示式之間的差異在於在區間向量表示式中我們需要定義時間選擇的範圍,時間範圍通過時間範圍選擇器[]進行定義。例如,通過以下表達式可以選擇最近5分鐘內的所有樣本資料:

http_request_total{}[5m]

該表示式將會返回查詢到的時間序列中最近5分鐘的所有樣本資料:

http_requests_total{code="200",handler="alerts",instance="localhost:9090",job="prometheus",method="get"}=[

[email protected]

[email protected]

[email protected]

[email protected]

[email protected]

[email protected]

]

http_requests_total{code="200",handler="graph",instance="localhost:9090",job="prometheus",method="get"}=[

4 @1518096812.326

[email protected]

[email protected]

[email protected]

[email protected]

[email protected]

]

通過區間向量表示式查詢到的結果我們稱為區間向量

除了使用m表示分鐘以外,PromQL的時間範圍選擇器支援其它時間單位:

  • s - 秒

  • m - 分鐘

  • h - 小時

  • d - 天

  • w - 周

  • y - 年

時間位移操作

在瞬時向量表示式或者區間向量表示式中,都是以當前時間為基準:

http_request_total{} # 瞬時向量表示式,選擇當前最新的資料

http_request_total{}[5m] # 區間向量表示式,選擇以當前時間為基準,5分鐘內的資料

而如果我們想查詢,5分鐘前的瞬時樣本資料,或昨天一天的區間內的樣本資料呢? 這個時候我們就可以使用位移操作,位移操作的關鍵字為offset

可以使用offset時間位移操作:


http_request_total{} offset 5m

http_request_total{}[1d] offset 1d

使用聚合操作

一般來說,如果描述樣本特徵的標籤(label)在並非唯一的情況下,通過PromQL查詢資料,會返回多條滿足這些特徵維度的時間序列。而PromQL提供的聚合操作可以用來對這些時間序列進行處理,形成一條新的時間序列:

# 查詢系統所有http請求的總量
sum(http_request_total)
# 按照mode計算主機CPU的平均使用時間
avg(node_cpu) by (mode)
# 按照主機查詢各個主機的CPU使用率
sum(sum(irate(node_cpu{mode!='idle'}[5m])) / sum(irate(node_cpu[5m]))) by (instance)

標量和字串

除了使用瞬時向量表示式和區間向量表示式以外,PromQL還直接支援使用者使用標量(Scalar)和字串(String)。

標量(Scalar):一個浮點型的數字值

標量只有一個數字,沒有時序。

例如:

10

需要注意的是,當使用表示式count(http_requests_total),返回的資料型別,依然是瞬時向量。使用者可以通過內建函式scalar()將單個瞬時向量轉換為標量。

字串(String):一個簡單的字串值

直接使用字串,作為PromQL表示式,則會直接返回字串。


"this is a string"

'these are unescaped: \n \\ \t'

`these are not unescaped: \n ' " \t`

合法的PromQL表示式

所有的PromQL表示式都必須至少包含一個指標名稱(例如http_request_total),或者一個不會匹配到空字串的標籤過濾器(例如{code="200"})。

因此以下兩種方式,均為合法的表示式:

http_request_total # 合法

http_request_total{} # 合法

{method="get"} # 合法

而如下表達式,則不合法:

{job=~".*"} # 不合法

同時,除了使用<metric name>{label=value}的形式以外,我們還可以使用內建的__name__標籤來指定監控指標名稱:

{__name__=~"http_request_total"} # 合法

{__name__=~"node_disk_bytes_read|node_disk_bytes_written"} # 合法