prometheus經常使用函數表達式

https://awesome-prometheus-alerts.grep.to/rules#elasticsearch 相關文檔javascript

Prometheus強大的地方就在於可使用不少計算公式去獲取本身須要的數據。正由於涉及到了計算公式,這也是它的難點所在,好比在Zabbix中要獲取CPU使用率是一件很簡單的事情,而在Prometheus中卻須要使用計算公式來完成。html

好比要統計CPU使用率:node_exporter會抓取CPU經常使用的8種狀態的累計工做時間,而後再用(全部非空閒狀態的CPU時間總和)/(全部狀態的CPU時間總和)= CPU使用率。而若是想要獲取中間某一分鐘的CPU平均時間還須要用到Counter數據類型。因爲Counter的數據一直是增量,因此須要截取其中一段增量值,而後再拿這個數值去套用公式進行計算。java


Prometheus爲不一樣的數據類型提供了很是多的計算函數,有個小技巧就是遇到counter數據類型,在作任何操做以前,先套上一個rate()或者increase()函數。下面介紹一些比較經常使用的函數幫助理解:node

rate()函數:這是一個很是重要的函數,專門配合counter類型數據,取counter在這個時間段中的平均每秒增量。好比監控網絡接受字節數的狀況,在9:10到9:20期間累計量增長了1000bytes,加入rate([1m])函數後就會使用1000除以60秒,計算出數據大約爲16bytes。linux

1 rate(  node_network_receive_bytes[1m] )  #獲取1分鐘內每秒的增量


increase函數和rate()函數同樣也是配合Counter使用。區別就是它是取其中一段時間的增量而不是平均值,好比bash

1 increase(node_cpu[1m])  #獲取CPU總使用時間1分鐘的增量


sum函數:在實際工做中CPU大可能是多核的,而node_cpu會將每一個核的數據都單獨顯示出來,咱們其實不會關注每一個核的單獨狀況,而是關心總的CPU狀況。使用sum()函數進行求和後能夠得出一條總的數據,但sum()是將全部機器的數據都進行了求和,因此還要再使用by (instance)或者by (cluster_name)就能夠取出單個服務器或者一組服務器的CPU數據。上面的公式能夠進化爲:服務器

1 sum( increase(node_cpu[1m]) )


count函數該函數用於進行一些模糊判斷,好比有100臺服務器在監控,想實現當CPU使用率大於80%的機器達到N臺就進行報警就可使用它網絡

1 count(count_netstat_wait_connections > 200)


topk函數:該函數能夠從大量數據中取出排行前N的數值,N能夠自定義。好比監控了100臺服務器的320個CPU,用這個函數就能夠查看當前負載較高的那幾個,用於報警elasticsearch

1 topk(3,count_netstat_wait_connections)  #Gauge類型


2 topk(3,,rate(node_network_receive_bytes[20m]))  #Counter類型


absent()

absent(v instant-vector) 若是傳遞給它的向量具備任何元素,則返回空向量;若是傳遞給它的向量沒有元素,則返回值爲1的1元素向量。ide

這對於在給定度量標準名稱和標籤組合不存在時間序列時發出警報很是有用。

absent(nonexistent{job="myjob"})
# => {job="myjob"}
absent(nonexistent{job="myjob",instance=~".*"})
# => {job="myjob"}
absent(sum(nonexistent{job="myjob"}))
# => {}

在第二個示例中,absent()嘗試從輸入向量中導出1元素輸出向量的標籤。

delta()函數

delta(v range-vector)計算範圍向量v中每一個時間系列元素的第一個和最後一個值之間的差值,返回具備給定增量和等效標籤的即時向量。 delta被外推以覆蓋範圍向量選擇器中指定的全時間範圍,所以即便樣本值都是整數,也能夠得到非整數結果。

如下示例表達式返回如今和2小時以前CPU溫度的差別:

delta(cpu_temp_celsius{host="zeus"}[2h])

delta應僅用於儀表。


changes()函數

changes(v range-vector) 輸入一個區間向量, 返回這個區間向量內每一個樣本數據值變化的次數(瞬時向量)。例如

# 若是樣本數據值沒有發生變化,則返回結果爲 1changes(node_load5{instance="192.168.1.75:9100"}[1m]) # 結果爲 1



predict_linear函數:對曲線變化速率進行計算,起到必定的預測做用。好比當前這1個小時的磁盤可用率急劇降低,這種狀況可能致使磁盤很快被寫滿,這時可使用該函數,用當前1小時的數據去預測將來幾個小時的狀態,實現提早告警

1 predict_linear( node_filesystem_free_bytes{mountpoint="/"}[1h],4*3600 ) < 0   #若是將來4小時後磁盤使用率爲負數就會報警



瞭解清楚流程以後進行一個CPU使用率的拆分解析:

一、先把key找出來,好比是爲了查看CPU的使用率,那麼就應該使用node_cpu這個key

二、在node_cpu這個key的基礎上把idle的CPU時間和所有CPU時間過濾出來,使用{}作過濾,以下:

1 node_cpu{ mode='idle' }  #找出空閒CPU的值
2 node_cpu  #不寫其餘參數表明ALL


三、使用increase()函數把1分鐘的數據抓取出來,這個時候取出來的是每一個CPU的數據

1 increase(node_cpu{mode='idle'}[1m])


四、使用sum()函數求和每一個CPU的數據,獲得單獨一個數據

1 sum( increase(node_cpu{mode='idle'}[1m]) )


五、sum()函數雖然把每一個CPU的數據進行了求和,可是還把每臺服務器也進行了求和,全部服務器的CPU數據都相同了,還須要進行一次處理。這裏又引出了一個新函數 by (instance)。它會把sum求和到一塊兒的數值按照指定方式進行拆分,instance表明的是機器名。若是不寫by (instance)的話就須要在{}中寫明須要哪一個實例的數據。

1 sum( increase(node_cpu{mode='idle'}[1m]) ) by (instance)  #空閒CPU一分鐘增量


六、最終計算出CPU使用率

1 1-( sum( increase(node_cpu{mode='idle'}[1m]) ) by (instance) / sum(increase(node_cpu[1m])) by (instance) ) *100



附上三個經常使用的計算公式:

查看源碼打印?

1 #CPU使用率
2 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
3 #內存使用率
4 (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100
5 #空閒內存剩餘率
6 100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100
7 #磁盤使用率
8 100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs"} / node_filesystem_size_bytes{mountpoint="/",fstype=~"ext4|xfs"} * 100)
相關文章
相關標籤/搜索