聚合操作使用語法:
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
sum (求和) min (最小值) max (最大值) avg (平均值) stddev (標准差) stdvar (標准差異) count (計數) count_values (對value進行計數) bottomk (后n條時序) topk (前n條時序) quantile (分布統計)
例子:匹配出 linux CPU 使用率大於80%
100 -avg(irate(node_cpu_seconds_total{owner="devops",envtype=~"product",mode="idle"}[5m])) by (instance)* 100 > 80
Counter 只增不減的計數器
Counter類型的指標其工作方式和計數器一樣,只增不減 (除非系統發生重置) , 常見的監控指標,如http_requests_total,node_cpu都是Counter類型的監控指標 , 一般在定義Counter類型指標的名稱時推薦使用_total作為后綴。
例如: 通過rate() 函數獲取HTTP請求量的增長率
rate(http_requests_total[5m])
查詢當前系統中,訪問量前十的HTTP地址
topk(10, http_reqursts_total)
Gauge 可增可減的儀表盤
Gauge類型的指標側重於反應系統的當前狀態,常見指標如:node_memory_MemFree(主機當前空閑的內容大小)、node_memory_MemAvailable(可用內存大小)
直接查看當前系統狀態 node_memory_MemFree 對於Gauge類型的監控指標,通過PromQL內置函數delta()可以獲取樣本在一段時間返回內的變化情況 計算CPU溫度在兩個小時內的差異 delta(cpu_temp_celsius{host="zeus"}[2h]) 還可以使用deriv()計算樣本的線性回歸模型,還可用predict_linear()對數據的變化趨勢進行預測 預測系統磁盤空間在4個小時之后的剩余情況: predict_linear(node_filesystem_free{job="node"}[1h], 4 * 3600)
PromQL 操作符
數學運算符: + (加法) - (減法) * (乘法) 1/ (除法) % (求余) ^ (冪運算)
布爾運算符: == (相等) != (不相等) > (大於) < (小於) >= (大於等於) <= (小於等於)
集合運算符: and(並且) or(或者) inless(排除)
匹配模式: =(等於) !=(不等於)
時間范圍單位: s - 秒 m - 分鍾 h - 小時 d - 天 w - 周 y - 年
操作符優先級和小學做算術題一樣,先乘除再加減,先大括號再小括號
類似MySQL的查詢結果做運算
查詢 rate irate
該函數用來計算某個指標在最近的一個區間時間內的變化率
比如說 Prometheus沒15秒采集一次數據,一分鍾采集四次數據,計算邏輯如下:
rate : 1m內,找到這四個采集點,然后用該區間最后一個采集點與第一個采集點的value差,除以這兩個采集點的時間差(s),相當於求出每一秒的平均數據
irate:該函數與rate函數不同的是,它是用區間內的最后一個采集點與倒數第二個采集點的value差,除以這兩個采集點的時間差
聯合查詢 多對一 & 一對多
多對一和一對多兩種匹配模式指的是 一側 的每一個向量元素可以與 多側 的 多個 元素匹配的情況,在這種情況下,必須用 group 修飾符
group_left 或者 group_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>
多對一和一對多兩種模式一定是出現在操作符兩側表達式返回的向量標簽不一致的情況。因此需要使用 ignoring 和 on 修飾符來排除或者限定匹配的標簽列表。
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
該表達式中,左向量 method_code:http_errors:rate5m 包含兩個標簽 method 和 code。而右向量 method:http_requests:rate5m 中只包含一個標簽 method,因此匹配時需要使用 ignoring 限定匹配的標簽為 code。 在限定匹配標簽后,右向量中的元素可能匹配到多個左向量中的元素 因此該表達式的匹配模式為多對一,需要使用 group 修飾符 group_left 指定左向量具有更好的基數。
計算結果 {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
一個具體的例子 參考:https://blog.csdn.net/lwlfox/article/details/103858180
有查詢語句1(得到溫度傳感器的名稱):
node_hwmon_sensor_label{instance="192.168.1.100", label=~"core_.*"}
得到結果:
node_hwmon_sensor_label{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_0", sensor="temp2"} 1 node_hwmon_sensor_label{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_1", sensor="temp3"} 1 node_hwmon_sensor_label{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_2", sensor="temp4"} 1 node_hwmon_sensor_label{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_3", sensor="temp5"} 1
有查詢語句2(得到溫度傳感器的溫度值):
node_hwmon_temp_celsius{instance="192.168.1.100", chip=~".+core.+"}
得到結果:
node_hwmon_temp_celsius{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", sensor="temp1"} 37 node_hwmon_temp_celsius{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", sensor="temp2"} 34 node_hwmon_temp_celsius{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", sensor="temp3"} 37 node_hwmon_temp_celsius{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", sensor="temp4"} 35 node_hwmon_temp_celsius{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", sensor="temp5"} 34
遇到的問題是:在查詢語句2中得到的結果沒有標識此溫度傳感器叫什么名字,對應到哪個核心CPU上,此名字在查詢語句1中可以得到,
所以,目標就是通過一行查詢語言,得到溫度的同時,也可以得到此傳感器對應到哪個CPU核心上。這兩個結果中,可以通過sensor="tempX"進行關聯,則有如下語句:
0 * node_hwmon_sensor_label{instance="192.168.1.100", label=~"core_.*"} + on (sensor) group_left(node_hwmon_temp_celsius) node_hwmon_temp_celsius{instance="192.168.1.100", chip=~".+core.+"}
得到結果:
{chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_0", sensor="temp2"} 33 {chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_1", sensor="temp3"} 36 {chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_2", sensor="temp4"} 35 {chip="platform_coretemp_0", instance="192.168.1.100", job="node-development", label="core_3", sensor="temp5"} 34
聚合操作
stddev (標准差) stdvar (標准差異) count (計數) count_values (對 value 進行計數) bottomk (樣本值最小的 k 個元素) topk (樣本值最大的k個元素) quantile (分布統計)
內置的聚合操作符可以將瞬時的表達式返回的樣本數據進行聚合,形成一個具有較少樣本值的新的時間序列
這些操作符被用於聚合所有標簽維度,或者通過without 或者 by 自語句來保留不同的維度
without
用於從計算結果中移除列舉的標簽,而保留其它標簽。by
則正好相反,結果向量中只保留列出的標簽,其余標簽則移除。通過 without 和 by 可以按照樣本的問題對數據進行聚合。
例如: sum(http_requests_total) without (instance) 等價於 sum(http_requests_total) by (application, group)
count_values 用於時間序列中每一個樣本值出現的次數,count_values 會為每一個唯一的樣本值輸出一個時間序列,並且每一個時間序列包括一個額外的標簽。
例如:統計同版本的二進制文件數量 count_values("version", build_version) 返回結果如下: {count="641"} 1 {count="3226"} 2 {count="644"} 4