Prometheus監控(二)

Prometheus監控(二)

數據類型

Counter(計數器類型)html

Counter類型的指標的工做方式和計數器同樣,只增不減(除非系統發生了重置),Counter通常用於累計值。node

Gauges(儀表盤類型)linux

Gauges是可增可減的指標類,能夠用於反應當前應用的狀態。好比在監控主機時,可用內存大小。ios

Histograms(直方圖類型)nginx

主要用於表示一段時間範圍內對數據進行採樣(一般是請求持續時間或響應大小),並可以對其指定區間以及總數進行統計,表明的是⼀種近似的百分⽐估算數值。舉例說明: 若是你想監控用戶的訪問時間,將nginx日誌的http_response_time列的數據所有采集下來,而後算一下總的平均值便可。可是這沒有意義,若是隻有一個用戶請求特別慢,那麼就會拉低總的平均值,並且你也發現不了小部分的問題。這時可使用histogram來比較~=0.05秒的量有多少,0 ~ 0.05秒的有多少,>2秒的有多少,>10秒的有多少。git

Summary(摘要類型)github

Summary 和 Histogram 相似,主要用於表示一段時間內數據採樣結果(一般時請求持續時間或響應大小),它直接存儲了quantile數據,而不是根據統計區間計算出來的。web

標籤匹配運算符

  • =:選擇與提供的字符串徹底相同的標籤。
  • !=:選擇不等於提供的字符串的標籤。
  • =~:選擇正則表達式匹配提供的字符串(或子字符串)的標籤。
  • !~:選擇不與提供的字符串(或子字符串)匹配的標籤。

註釋: 標籤名稱的匹配可使用以下方示例:正則表達式

(1)http_requests_total{environment=~"staging|testing|development",method!="GET"}
(2)http_requests_total{job=~".+",method!="GET"}
(3)http_requests_total{job=~".",method!="GET"}*vim

範圍向量選擇器

時間長度被追加在向量選擇器尾部的方括號[]中,用以指定對於每一個樣本範圍區間中的每一個元素應該抓取的時間範圍樣本區間。

  • s - seconds
  • m - minutes
  • h - hours
  • d - days
  • w - weeks
  • y - years

示例: 取出過去5分鐘內,度量指標名稱爲http_requests_total,標籤爲job="prometheus"的時間序列數據
http_requests_total{job="prometheus"}[5m]

位置修飾符

offset偏移修飾符,容許在查詢中改變單個瞬時向量和範圍向量中的時間偏移

示例: 取出相對於當前時間的前一週,過去五分鐘的http_requests_total的速率:
rate(http_requests_total[5m] offset 1w)

邏輯/集二元運算符(邏輯/集合二元操做符)

  • and 交集
  • or 並集
  • unless 補集

vector1 and vector2 的邏輯/集合二元操做符,規則:vector1瞬時向量中的每一個樣本數據與vector2向量中的全部樣本數據進行"標籤"匹配,不匹配的,所有丟棄。運算結果是保留左邊的度量指標名稱和值。
示例:

公式:
node_cpu_seconds_total{job='test',cpu='1',mode=~"idle|system|user"}  and node_cpu_seconds_total{mode=~"system|user"}
返回的結果:
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test",mode="user"}
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test",mode="system"}

vector1 or vector2 的邏輯/集合二元操做符,規則:返回vector1中的全部元素和值,以及vector2中沒有在vector1中匹配到的元素.
示例:

公式:
node_cpu_seconds_total{job='test',cpu='1',mode=~"user"} or node_cpu_seconds_total{cpu='1',job='test2',mode=~"system|user"}
返回的結果:
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test",mode="user"}   22.92
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test2",mode="system"}    54.14
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test2",mode="user"}   22.91

vector1 unless vector2的邏輯/集合二元操做符,又稱差積。規則:包含在vector1中的元素,可是該元素不在vector2向量全部元素列表中,則寫入到結果集中。
示例:

公式:
node_cpu_seconds_total{job='test',cpu='1',mode=~"user|system|idle"} unless node_cpu_seconds_total{mode=~"system|user"}
返回的結果:
node_cpu_seconds_total{cpu="1",instance="gitlab:9100",job="test",mode="idle"}

聚合運算符:

Prometheus支持下面的內置聚合操做符。這些聚合操做符被用於聚合單個即時向量的全部時間序列列表,把聚合的結果值存入到新的向量中。

(1). sum (在全部的value上求和)
sum(node_cpu_seconds_total{job="test"})
(2). max (在全部的value求最大值)
max(node_cpu_seconds_total{job="test"})
(3). min (在全部的value求最小值)
min(node_cpu_seconds_total{job="test"})
(4). avg (在全部的value上求平均值)
avg(node_cpu_seconds_total{job="test"})
(5). stddev (求標準差)
(6). stdvar (求方差)
(7). count (統計向量元素的個數)
count(node_cpu_seconds_total{job="test"}) 
(8). count_values (統計相同數據值的元素數量)
count_values("tag",node_cpu_seconds_total{cpu="0",mode="nice"}) #tag是標籤名
(9). bottomk (在維度上取幾個最小值)
bottomk(3,node_cpu_seconds_total{instance="gitlab:9100",cpu="0",mode=~"idle|nice|softirq"})
(10). topk (在維度上取幾個最大值)
topk(3,node_cpu_seconds_total{instance="gitlab:9100",cpu="0",mode=~"idle|nice|softirq"})
(11). quantile (統計分位數)
quantile(0.99,prometheus_http_request_duration_seconds_sum{handler!="/metrics"})   #值爲0.38表明百分之99的請求都在0.38ms下。
(12). sort(排序)
(13). time(打印當前時間戳)
(14). sqrt(計算元素的平方根)
(15). timestamp(返回樣本的時間戳(不是當前時間戳))

功能性函數說明

(1). increase()
increase(node_cpu_seconds_total{mode="idle"}[1m])    
#返回一個度量標準: last值-first值。取⼀段時間增量的總量  
(2). by()
count(node_cpu_seconds_total{mode="idle"}) by(cpu)   
#這個函數,能夠把sum加合到⼀起的數值,按照指定的⼀個⽅式進⾏⼀層的拆分
(3). rate()  
#rate函數是專門搭配counter類型數據使⽤的函數它的功能是按照設置⼀個時間段,(last值-first值)/時間差s,取⼀段時間增量的平均每秒數量. 
(4). predict_limpar(預測函數)
predict_linear(node_filesystem_free_bytes{device="/dev/sda3",fstype="xfs",instance="jenkins:9100",job="test2",mountpoint="/"}[1m],300)
#根據磁盤1分鐘內的變化,預測5分鐘後的值
(5). abs()
#返回輸入向量的全部樣本的絕對值。
(6). absent()
#若是賦值給它的向量具備樣本數據,則返回空向量;若是傳遞的瞬時向量參數沒有樣本數據,則返回不帶度量指標名稱且帶有標籤的樣本值爲1的結果,當監控度量指標時,若是獲取到的樣本數據是空的, 使用absent方法對告警是很是有用的.(有數據返回空,沒數據返回1)
(7). ceil
#返回一個向上舍入爲最接近的整數。
(8). changes()
changes(node_filesystem_free_bytes[1m])
#changes(v range-vector) 輸入一個範圍向量, 返回這個範圍向量內每一個樣本數據值變化的次數。
(9). clamp_max()
#clamp_max(v instant-vector, max scalar)函數,輸入一個瞬時向量和最大值,樣本數據值若大於max,則改成max,不然不變
(10). clamp_min()
#輸入一個瞬時向量和最大值,樣本數據值小於min,則改成min。不然不變
(11). hour,minute,month,year,day_of_month(),day_of_week(),days_in_month()
#當前的小時,分鐘,月,年,當天在這個月是第幾天,當天在這個星期是第幾天,這個月有多少天.
(12). delta()
delta(node_cpu_seconds_total{cpu="0",instance="gitlab:9100",job="test",mode="idle"}[1m])
#delta(v range-vector)函數,計算一個範圍向量v的第一個元素和最後一個元素之間的差值。返回值:key:value=度量指標:差值
(13). floor()
#此函數,與ceil()函數相反。 4.3 爲 4 。
(14). exp()
#輸入一個瞬時向量, 返回各個樣本值的e指數值,即爲e^N次方,e=2.718281828,N=Value。
(15). idelta()
#idelta(v range-vector) 的參數是一個區間向量, 返回一個瞬時向量。它計算最新的 2 個樣本值之間的差值。這個函數通常只用在 Gauge 類型的時間序列上。
(16). label_join()
label_join(up{instance="localhost:9091",job="pushgateway"},"foo", ",", "job","instance")
=》up{foo="pushgateway,localhost:9091",instance="localhost:9091",job="pushgateway"}
#函數能夠將時間序列 v 中多個標籤 src_label 的值,經過 separator做爲鏈接符寫入到一個新的標籤 dst_label 中。能夠有多個 src_label 標籤。
(17). label_replace()
label_replace(up{instance="jenkins:9100",job="test2"},"port", "$2", "instance","(.*):(.*)")
=> up{instance="jenkins:9100",job="test2",port="9100"}
#label_replace 函數爲時間序列添加額外的標籤。該函數會依次對 v 中的每一條時間序列進行處理,經過 regex 匹配 src_label 的值,並將匹配部分 relacement 寫入到 dst_label 標籤中。
(18). round()
#round()函數與 ceil 和 floor 函數相似,返回向量中全部樣本值的最接近的整數。
(19). vector()
#將標量返回s爲沒有標籤的向量。
(20). irate()
irate(node_load1[1m])
#irate(v range-vector)函數, 輸入:範圍向量,輸出:key: value = 度量指標: (last值-last前一個值)/時間戳差值,它是基於最後兩個數據點。
(21). <aggregation>_over_time()
#如下函數容許聚合給定範圍向量的每一個系列隨時間的變化並返回具備每系列聚合結果的即時向量:
- avg_over_time(range-vector):指定時間間隔內全部點的平均值。
avg_over_time(node_cpu_seconds_total{cpu="0",instance="gitlab:9100",job="test",mode="idle"}[1m])
- min_over_time(range-vector):指定時間間隔內全部點的最小值。
- max_over_time(range-vector):指定時間間隔內全部點的最大值。
- sum_over_time(range-vector):指定時間間隔內全部值的總和。
- count_over_time(range-vector):指定時間間隔內全部值的計數。
- quantile_over_time(scalar, range-vector):指定間隔中的值的φ-分位數(0≤φ≤1)。
#中分位的計算方法:若是數字個數爲奇數,中位值就是中間那個數,若是是偶數,則是中間兩個數的平均數。
#90百分位數的計算方式: a=[1,2,3,4]
a. (n-1)*p=(4-1)*0.9=2.7  #則整數部分i=2,小數部分j=0.7,n=數字個數,p=90百分位數。
b. a[i]=3;a[i+1]=4
c. (1-0.7)*3+(0.7*4)=3.7
- stddev_over_time(range-vector) : 區間向量內每一個度量指標的整體標準差。
#整體標準差計算方法:
步驟1、(每一個樣本數據 減去整體所有數據的平均值)。
步驟2、把步驟一所得的各個數值的平方相加。
步驟3、把步驟二的結果除以 n (「n」指整體數目)。
步驟4、從步驟三所得的數值之平方根就是整體的標準誤差。
- stdvar_over_time(range-vector) : #區間向量內每一個度量指標的整體標準方差,計算方法至關於沒有第四步的整體標準差方法。

系統監控命令行

系統負載

node_load1   #系統一分鐘內的負載
node_load5
node_load15

CPU

使用率:
100 - (avg(irate(node_cpu_seconds_total{instance=~"jenkins",mode="idle"}[5m])) * 100)
等待:
avg(irate(node_cpu_seconds_total{instance=~"jenkins",mode="iowait"}[5m])) * 100

內存

總大小:
node_memory_MemTotal_bytes{instance=~"jenkins"}
使用率:
(1 - (node_memory_MemAvailable_bytes{instance=~"jenkins"} / (node_memory_MemTotal_bytes{instance=~"jenkins"})))* 100

硬盤

總大小:
node_filesystem_size_bytes {instance=~"jenkins",fstype=~"ext4|xfs"}
剩餘大小:
node_filesystem_avail_bytes {instance=~'jenkins:9100',fstype=~"ext4|xfs"}
使用率:
1-(node_filesystem_free_bytes{instance=~'jenkins:9100',fstype=~"ext4|xfs"} / node_filesystem_size_bytes{instance=~'jenkins:9100',fstype=~"ext4|xfs"})
IOPS:
磁盤每秒讀取速率: irate(node_disk_reads_completed_total{instance=~"jenkins:9100"}[1m])
磁盤每秒寫入速率: irate(node_disk_writes_completed_total{instance=~"jenkins:9100"}[1m])
磁盤讀延遲(ms): irate(node_disk_read_time_seconds_total{instance=~"gitlab:9100"}[1m])
磁盤寫延遲(ms): irate(node_disk_write_time_seconds_total{instance=~"gitlab:9100"}[1m])

文件句柄

系統當前打開的文件句柄:
node_filefd_allocated{instance=~"jenkins"}  #這個值是從/proc/sys/fs/file-nr獲取到的

網絡

入網: irate(node_network_receive_bytes_total{instance=~'$node',device!~'tap.*'}[5m])
出網:irate(node_network_transmit_bytes_total{instance=~'$node',device!~'tap.*'}[5m])

監控報警(alertmanager)

安裝alertmanager
wget http://github.com/prometheus/alertmanager/releases/download/v0.16.1/alertmanager-0.16.1.linux-amd64.tar.gz
tar xf alertmanager-0.16.1.linux-amd64.tar.gz -C /usr/local/
mv /usr/local/alertmanager-0.16.1.linux-amd64 /usr/local/alertmanager
./alertmanager --config.file /usr/local/alertmanager/alertmanager.yml --web.external-url='http://192.168.18.213:9093'   #--web.external-url是報警是顯示的遠程地址

郵件報警

1. prometheus.yml添加添加alertmanager信息
[root@nagios alertmanager]# cat ../prometheus/prometheus.yml
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - localhost:9093        #alertmanager的遠程地址

rule_files:
  - "/usr/local/prometheus/rules.yml"   #匹配的規則文件

2. 修改rules.yml文件
[root@nagios alertmanager]# cat /usr/local/prometheus/rules.yml
groups:
- name: node_memory
  rules:
  - alert: "內存告警"  #報警名稱
    expr: (1- (node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes))*100 > 80
    for: 15s  #每隔15秒檢測一次
    labels:   #標籤
      severity: warning 
    annotations:    #描述
      summary: "The percentage of memory exceeded the limit is now {{$value}} percent"

3.修改alertmanager配置文件
[root@nagios alertmanager]# cat alertmanager.yml
global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.doormobi.com:25' # 郵箱smtp服務器代理
  smtp_from: 'jenkins@doormobi.com' # 發送郵箱名稱
  smtp_auth_username: 'jenkins@doormobi.com' # 郵箱名稱
  smtp_auth_password: 'xxxxx' # 郵箱密碼或受權碼
  smtp_require_tls: false   #不使用tls加密 

templates:
  - 'template/*.tmpl'  #配置要發送信息的模板,基於當前目錄。

route:  #定義路由信息
  receiver: 'email'  #發送警報的接收者的名稱,如下receivers name的名稱
  group_by: ['alertname']
  group_wait: 5s
  group_interval: 1m
  repeat_interval: 1m

receivers:
- name: 'email'
  email_configs:
    - to: 'yuliang.zhu@qizhixinxi.com'
      headers: { Subject: "[WARN] 報警郵件"} # 接收郵件的標題
      send_resolved: true  #告警解除後否發送通知,這裏選擇發送

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

4. 編寫報警模板
[root@nagios alertmanager]# cat template/test.tmpl 
{{ define "email.default.html" }}
{{ range .Alerts }}
========start==========<br/>
告警程序: prometheus_alert<br/>
告警詳情: {{ .Annotations.summary }}<br/>
告警級別: {{ .Labels.severity }}<br/>
告警類型: {{ .Labels.alertname }}<br/>
故障主機: {{ .Labels.instance }}<br/>
觸發時間: {{ .StartsAt.Format "2006-01-02 15:04:05" }}<br/>
========end==========<br/>
{{ end }}
{{ end }}

報警效果:

微信報警

1. 修改alertmanager配置文件
[root@nagios alertmanager]# vim alertmanager.yml
route:
  receiver: 'email'
  group_by: ['alertname']
  group_wait: 5s
  group_interval: 15s
  repeat_interval: 15s
  routes:
  - receiver: 'weixing'
    match_re:
      severity: 'warning'
receivers:
- name: 'email'
  email_configs:
    - to: 'yuliang.zhu@qizhixinxi.com'
      headers: { Subject: "[WARN] 報警郵件"} # 接收郵件的標題
- name: 'weixing'
  wechat_configs:
  - send_resolved: true #告警解除後否發送通知,這裏選擇發送
    corp_id: 'wx7982c7fdf4eac184'
    api_secret: 'kUc_0gVzCPe2qQ8E8ckY7qcaGEuIzuAknGjibh8xxx--'
    to_party: '5'
    agent_id: '1000003'

2. 添加報警模板
[root@nagios alertmanager]# cat template/wechat.tmpl 
{{ define "wechat.default.message" }} #此處與郵件不一樣
{{ range .Alerts }}
========start==========
告警程序: prometheus_alert
告警級別: {{ .Labels.severity }}
告警類型: {{ .Labels.alertname }}
故障主機: {{ .Labels.instance }}
觸發時間: {{ .StartsAt.Format "2006-01-02 15:04:05" }}
告警詳情: {{ .Annotations.summary }}
========end==========
{{ end }}
{{ end }}

釘釘報警

1.安裝prometheus,釘釘報警插件
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v0.3.0/prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz
tar xf prometheus-webhook-dingtalk-0.3.0.linux-amd64.tar.gz -C /usr/local/
mv /usr/local/prometheus-webhook-dingtalk-0.3.0.linux-amd64 /usr/local/prometheus-webhook-dingtalk
/usr/local/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk --ding.profile="ops_dingding=釘釘機器人地址" &

2. 修改alertmanager配置文件
[root@nagios alertmanager]# vim alertmanager.yml
route:
  receiver: 'email'
  group_by: ['alertname']
  group_wait: 5s
  group_interval: 15s
  repeat_interval: 15s
  routes:
  - receiver: 'weixing'
    match_re:
      severity: 'warning'
  - receiver: 'webhook'
    match_re:
     severity: 'warning'
receivers:
- name: 'email'
  email_configs:
    - to: 'yuliang.zhu@qizhixinxi.com'
      headers: { Subject: "[WARN] 報警郵件"}   #接收郵件的標題
- name: 'weixing'
  wechat_configs:
  - send_resolved: true    #告警解除後否發送通知,這裏選擇發送
    corp_id: 'wx7982c7fdf4eac184'
    api_secret: 'kUc_0gVzCPe2qQ8E8ckY7qcaGEuIzuAknGjibh8xxx--'
    to_party: '5'
    agent_id: '1000003'
- name: 'webhook'
  webhook_configs:
    - url: http://localhost:8060/dingtalk/ops_dingding/send   #剛纔安裝的釘釘插件
      send_resolved: true