PromQL(Prometheus Query Language)主要用來查詢和分析監控數據,而 PromQL 內部的數據類型決定了查詢的結果是什麼樣的數據。這些數據類型就像不同的「資料容器」,用來存放與處理監控數據。
基本概念
PromQL(Prometheus Query Language)主要用來查詢和分析監控數據,數據的來源為 Exporter 所回傳的指標數據 ( Metric),每個 Metric 可能包含 Label(標籤) 來區分不同的資料。
PromQL 主要有以下數據類型:
- 瞬時向量(Instant Vector)
- 區間向量(Range Vector)
- 標量(Scalar)
以下詳細介紹:
Instant Vector
: 瞬時向量
定義
瞬時向量是一組時間序列(Time Series),但 每個時間序列只包含一個數據點,代表某個特定時間點的監控數據。
特點
- 包含多個時間序列,每個時間序列都有 唯一一個時間點的值。
- 用來查詢「當前時刻」的監控數據。
- 是 PromQL 最常見 的數據類型。
比喻
- 快照:像是一張照片,記錄了某個時間點的監控數據。
範例
假設 Prometheus 監控了一個伺服器
server1
的 CPU 使用率,使用以下查詢:這將返回
server1
當前時刻 的 CPU 使用率,例如:Range Vector
: 區間向量
定義
區間向量是 一段時間範圍內的多個數據點,代表時間序列在一個區間內的歷史變化。
特點
- 包含多個時間序列,每個時間序列內有 多個數據點(不同時間點的數值)。
- 主要用於計算 趨勢 或 統計分析(例如計算平均值、最大值等)。
- 需要 指定一個時間範圍(如 5 分鐘、1 小時等)。
比喻
- 影片:像是一段監控錄影,記錄了某個時間區間內的變化。
樣式表
ms | 毫秒 | d | 日 |
s | 秒 | w | 周 |
m | 分鐘 | y | 年 |
h | 小時 | ㅤ | ㅤ |
範例
查詢
server1
過去 5 分鐘內 的 CPU 使用率變化:返回的結果可能是:
這表示
server1
的 CPU 使用率在這 5 分鐘內的變化趨勢。Scalar
: 標量
定義
標量是 單一的數值,用來進行計算、比較或作為閾值(Threshold)。
特點
- 只是一個簡單的數字或字串,不包含時間資訊。
- 主要用來 進行數學計算 或 比較數值。
範例
Operators : 運算子
算術運算子
算術運算如果是兩個即時向量相加,會消除沒交集資訊 (inner join)
寫法
+ | 相加 | / | 取商數 |
- | 相減 | % | 取餘數 |
* | 乘法 | ^ | 指數 |
範例:
A | ㅤ | B | ㅤ | A + 5 | ㅤ | A + B | ㅤ |
M1{a} | 3 | M1{a} | 37 | M1{a} | 8 | M1{a} | 40 |
M1{b} | 4 | M1{b} | 6 | M1{b} | 9 | M1{b} | 10 |
M1{c} | 5 | ㅤ | ㅤ | M1{c} | 10 | ㅤ | ㅤ |
M1{d} | 1 | ㅤ | ㅤ | M1{d} | 6 | ㅤ | ㅤ |
M1{e} | 0 | ㅤ | ㅤ | M1{e} | 5 | ㅤ | ㅤ |
M1{f} | 1 | ㅤ | ㅤ | M1{f} | 6 | ㅤ | ㅤ |
二元運算子
Prometheus 使用 1/0 表達 True/False,1 - True, 0 - False
== | 相等 | < | 小於 |
!= | 不相等 | >= | 大於等於 |
> | 大於 | <= | 小於等於 |
集合運算子
集合運算子只能用在即時向量上。
寫法
and | 交集 |
or | 聯集 |
unless | 保留左側有但右側沒有的數據 |
範例
A | M{a}: 10, M{b}: 5 |
B | M{a}: 10, M{c}: 8 |
A and B | M{a}: 10 |
A or B | M{a}: 10, M{b}: 5 M{c}: 8 |
A unless B | M{b}: 5 |
函示
PromQL 內建許多函示,使用
函示名()
來呼叫使用來,以下根據種類分類聚合函示
函數 | 說明 | 範例 |
sum(vector) | 對所有數據求和 | sum(http_requests_total) |
avg(vector) | 計算平均值 | avg(rate(node_cpu_seconds_total[5m])) |
min(vector) | 取得最小值 | min(node_memory_Active_bytes) |
max(vector) | 取得最大值 | max(node_memory_Active_bytes) |
count(vector) | 計算數量 | count(up) |
group(vector) | 分組但不做計算(較少使用) | group(node_cpu_seconds_total) |
topk(k, vector) | 取得前 K 個最大值 | topk(5, avg(rate(http_requests_total[5m])) by (instance)) |
bottomk(k, vector) | 取得前 K 個最小值 | bottomk(3, sum(rate(node_cpu_seconds_total[5m])) by (instance)) |
stddev(vector) | 計算標準差 | stddev(rate(node_cpu_seconds_total[5m])) |
stdvar(vector) | 計算變異數 | stdvar(rate(node_cpu_seconds_total[5m])) |
quantile(0.k, vector) | 計算分位數(常見 50%、90%、95%、99%) | quantile(0.95, rate(http_request_duration_seconds[5m])) |
數學函示
函數 | 說明 | 範例 |
abs(vector) | 取絕對值,將負數轉為正數 | abs(-5) |
ceil(vector) | 向上取整,返回大於等於數值的最小整數 | ceil(2.3) |
floor(vector) | 向下取整,返回小於等於數值的最大整數 | floor(2.9) |
round(vector) | 四捨五入(可選擇到幾位小數) | round(2.5) ,round(2.567, 2) |
exp(vector) | 計算 e^x(e=2.718) | exp(1) |
sqrt(vector) | 計算平方根 | sqrt(16) |
ln(vector) | 計算自然對數(logₑ) | ln(10) |
log2(vector) | 計算以 2 為底的對數(log₂) | log2(8) |
log10(vector) | 計算以 10 為底的對數(log₁₀) | log10(1000) |
clamp_max(vector, max) | 限制最大值,不超過 max | clamp_max([120, 90], 100) |
clamp_min(vector, min) | 限制最小值,不小於 min | clamp_min([120, 90], 100) |
pi() | 返回圓周率 π(3.14159) | pi() |
mod(vector, divisor) | 計算餘數(取模) | mod(10, 3) |
時間函示
函數 | 說明 | 範例 |
time() | 返回當前 Unix 時間戳(秒) | time() |
day_of_month(vector) | 返回當月的日期(1-31) | day_of_month(time()) |
day_of_week(vector) | 返回星期幾(0=星期日,1=星期一,...,6=星期六) | day_of_week(time()) |
day_of_year(vector) | 返回當年的第幾天(1-366) | day_of_year(time()) |
hour(vector) | 返回小時(0-23) | hour(time()) |
minute(vector) | 返回分鐘(0-59) | minute(time()) |
month(vector) | 返回月份(1-12) | month(time()) |
year(vector) | 返回年份(四位數) | year(time()) |
timestamp(vector) | 將時間轉換為 Unix 時間戳(秒) | timestamp(up) |
分組函示
函數 | 說明 | 範例 |
by(label) | 按標籤分組(要搭配聚合函數) | sum(rate(http_requests_total[5m])) by (method, path) |
without(label) | 移除某個標籤後分組 | sum(rate(http_requests_total[5m])) without (instance) |
特殊函示
函數 | 說明 | 範例 |
absent(instant vector) | 檢查即時向量是否為空,
如果沒值,返回 1
如果有值,就會返回空向量 | absent(node_cpu_seconds_total) |
absent_over_time(range vector) | 檢查範圍向量是否為空,
如果沒值,返回 1
如果有值,就會返回空向量 | absent_over_time(node_cpu_seconds_total[5m]) |
delta(range vector) | 計算範圍區間內第一個跟最後一個向量的差值 | delta(http_requests_total[5m])
|
idelta(range vector) | 計算範圍區間內最新兩個向量的差值 | idelta(http_requests_total[5m])
|
sort(instant vector) | 升序排序 | sort(http_requests_total)
|
sort_desc(instant vector) | 降序排序 | sort_desc(http_requests_total)
|
寫法
基本查詢
直接使用 Metric ,不做任何過濾
範例:
條件查詢
使用條件來篩選 Metric 的 label ,寫在
{}
中,支援以下條件運算符號 (注意不是上方的二元運算子):=
:等於
!=
:不等於
=~
:正則表達式匹配
!~
:正則表達式不匹配
範例
時間範圍查詢
PromQL 根據
Range Vector
: 區間向量 格式來查詢指定時段指標數據,使用 []
設定時間區間範例:
時間偏移查詢
PromQL 預設都是查詢即時向量,但如果想要查詢 “n分鐘前”,就需要
offset
關鍵字