Prometheus + Grafana詳解

一 概述

Prometheus 是一個開源監控系統,它前身是 SoundCloud的告警工具包。從 2012 年開始,許多公司和組織開始使用 Prometheus。該項目的開發人員和用戶社區很是活躍,愈來愈多的開發人員和用戶參與到該項目中。目前它是一個獨立的開源項目,且不依賴於任何公司。爲了強調這點和明確該項目治理結構,Prometheus 在 2016 年繼Kurberntes 以後,加入了 Cloud Native Computing Foundationnode

1.1 prometheus核心概念

1.1.1 數據模型

Prometheus 從根本上存儲的全部數據都是時間序列數據(Time Serie Data,簡稱時序數據)。時序數據是具備時間戳的數據流,該數據流屬於某個度量指標(Metric)和該度量指標下的多個標籤(Label)。除了提供存儲功能,Prometheus 還能夠利用查詢表達式來執行很是靈活和複雜的查詢。linux

  • 度量指標和標籤

每一個時間序列(Time Serie,簡稱時序)由度量指標和一組標籤鍵值對惟一肯定。ios

度量指標名稱描述了被監控系統的某個測量特徵(好比 http_requests_total 表示 http 請求總數)。度量指標名稱由 ASCII 字母、數字、下劃線和冒號組成,須匹配正則表達式 [a-zA-Z_:][a-zA-Z0-9_:]*git

標籤開啓了 Prometheus 的多維數據模型。對於同一個度量指標,不一樣標籤值組合會造成特定維度的時序。Prometheus 的查詢語言能夠經過度量指標和標籤對時序數據進行過濾和聚合。改變任何度量指標上的任何標籤值,都會造成新的時序。標籤名稱能夠包含 ASCII 字母、數字和下劃線,須匹配正則表達式 [a-zA-Z_][a-zA-Z0-9_]*,帶有 _ 下劃線的標籤名稱保留爲內部使用。標籤值能夠包含任意 Unicode 字符,包括中文。github

  • 採樣值(Sample)web

    時序數據其實就是一系列採樣值。每一個採樣值包括:正則表達式

    • 一個 64 位的浮點數值
    • 一個精確到毫秒的時間戳
  • 註解(Notation)docker

一個註解由一個度量指標和一組標籤鍵值對構成。形式以下:shell

[metric name]{[label name]=[label value], ...}
複製代碼

例如,度量指標爲 api_http_requests_total,標籤爲 method="POST"、handler="/messages" 的註解表示以下:數據庫

api_http_requests_total{method="POST", handler="/messages"}
複製代碼

1.1.2 度量指標類型

  • 計數器(Counter)

計數器是一種累計型的度量指標,它是一個只能遞增的數值。計數器主要用於統計相似於服務請求數、任務完成數和錯誤出現次數這樣的數據。

  • 計量器(Gauge)

計量器表示一個既能夠增長, 又能夠減小的度量指標值。計量器主要用於測量相似於溫度、內存使用量這樣的瞬時數據。

  • 直方圖(Histogram)

    直方圖對觀察結果(一般是請求持續時間或者響應大小這樣的數據)進行採樣,並在可配置的桶中對其進行統計。有如下幾種方式來產生直方圖(假設度量指標爲 ):

    • 按桶計數,至關於 <basename>_bucket{le="<upper inclusive bound>"}
    • 採樣值總和,至關於 <basename>_sum
    • 採樣值總數,至關於 <basename>_count ,也等同於把全部採樣值放到一個桶裏來計數 <basename>_bucket{le="+Inf"}
  • 彙總(Summary)

    相似於直方圖,彙總也對觀察結果進行採樣。除了能夠統計採樣值總和和總數,它還可以按分位數統計。有如下幾種方式來產生彙總(假設度量指標爲 ):

    • 按分位數,也就是採樣值小於該分位數的個數佔總數的比例小於 φ,至關於 <basename>{quantile="<φ>"}
    • 採樣值總和,至關於 <basename>_sum
    • 採樣值總數,至關於 <basename>_count

1.1.3 任務(Job)和實例(Instance)

在 Prometheus 裏,能夠從中抓取採樣值的端點稱爲實例,爲了性能擴展而複製出來的多個這樣的實例造成了一個任務。

例以下面的 api-server 任務有四個相同的實例:

job: api-server
instance 1: 1.2.3.4:5670
instance 2: 1.2.3.4:5671
instance 3: 5.6.7.8:5670
instance 4: 5.6.7.8:5671
複製代碼

Prometheus 抓取完採樣值後,會自動給採樣值添加下面的標籤和值:

  • job: 抓取所屬任務。
  • instance: 抓取來源實例

另外每次抓取時,Prometheus 還會自動在如下時序裏插入採樣值:

  • up{job="[job-name]", instance="instance-id"}:採樣值爲 1 表示實例健康,不然爲不健康
  • scrape_duration_seconds{job="[job-name]", instance="[instance-id]"}:採樣值爲本次抓取消耗時間
  • scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}:採樣值爲從新打標籤後的採樣值個數
  • scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}:採樣值爲本次抓取到的採樣值個數

1.2 prometheus特色

  • 多維度數據模型,一個時間序列由一個度量指標和多個標籤鍵值對肯定
  • 靈活的查詢語言,對收集的時許數據進行重組
  • 強大的數據可視化功能,除了內置的瀏覽器,也支持grafana集成
  • 高效存儲,內存加本地磁盤,可經過功能分片和聯盟來拓展性能
  • 運維簡單,只依賴於本地磁盤,go二進制安裝包沒有任何其餘依賴
  • 精簡告警
  • 很是多的客戶端庫
  • 提供了許多導出器來收集經常使用系統指標

1.3 altermanager 核心概念

1.3.1 分組

分組將相似性質的警報分類爲單個通知。在許多系統一次性失敗而且數百到數千個警報可能同時發生的較大中斷期間,這尤爲有用。

示例:發生網絡分區時,羣集中正在運行數十或數百個服務實例。一半的服務實例沒法再訪問數據庫。Prometheus中的警報規則配置爲在每一個服務實例沒法與數據庫通訊時發送警報。結果,數百個警報被髮送到Alertmanager。

做爲用戶,人們只想得到單個頁面,同時仍可以確切地看到哪些服務實例受到影響。所以,能夠將Alertmanager配置爲按羣集和alertname對警報進行分組,以便發送單個緊湊通知。

經過配置文件中的路由樹配置警報的分組,分組通知的定時以及這些通知的接收器。

1.3.2 抑制

若是某些其餘警報已經觸發,則抑制是抑制某些警報的通知的概念。示例:正在觸發警報,通知沒法訪問整個集羣。Alertmanager能夠配置爲在該特定警報觸發時將與該集羣有關的全部其餘警報靜音。這能夠防止數百或數千個與實際問題無關的觸發警報的通知。經過Alertmanager的配置文件配置禁止。

1.3.3 沉默

沉默是在給定時間內簡單地靜音警報的簡單方法。基於匹配器配置靜默,就像路由樹同樣。檢查傳入警報它們是否匹配活動靜默的全部相等或正則表達式匹配器。若是他們這樣作,則不會發送該警報的通知。在Alertmanager的Web界面中配置了靜音。

1.3.4 客戶端行爲

Alertmanager對其客戶的行爲有特殊要求。這些僅適用於不使用Prometheus發送警報的高級用例。

1.3.5 高可用

Alertmanager支持配置以建立用於高可用性的集羣。這可使用--cluster- *標誌進行配置。重要的是不要在Prometheus和它的Alertmanagers之間加載平衡流量,而是將Prometheus指向全部Alertmanagers的列表。

二 架構

2.1 prometheus架構圖

2.2 altermanager架構圖

三 與其餘監控系統對不

3.1 Prometheus vs. Zabbix

  • Zabbix 使用的是 C 和 PHP, Prometheus 使用 Golang, 總體而言 Prometheus 運行速度更快一點。
  • Zabbix 屬於傳統主機監控,主要用於物理主機、交換機、網絡等監控,Prometheus 不只適用主機監控,還適用於 Cloud、SaaS、Openstack、Container 監控。
  • Zabbix 在傳統主機監控方面,有更豐富的插件。
  • Zabbix 能夠在 WebGui 中配置不少事情,Prometheus 須要手動修改文件配置。、

3.2 Prometheus vs. Nagios

  • Nagios 數據不支持自定義 Labels, 不支持查詢,告警也不支持去噪、分組, 沒有數據存儲,若是想查詢歷史狀態,須要安裝插件。
  • Nagios 是上世紀 90 年代的監控系統,比較適合小集羣或靜態系統的監控Nagios 太古老,不少特性都沒有,Prometheus 要優秀不少。

3.3 Prometheus vs Sensu

  • Sensu 廣義上講是 Nagios 的升級版本,它解決了不少 Nagios 的問題,若是你對 Nagios 很熟悉,使用 Sensu 是個不錯的選擇。
  • Sensu 依賴 RabbitMQ 和 Redis,數據存儲上擴展性更好。

3.4 Prometheus vs InfluxDB

  • InfluxDB 是一個開源的時序數據庫,主要用於存儲數據,若是想搭建監控告警系統,須要依賴其餘系統。
  • InfluxDB 在存儲水平擴展以及高可用方面作的更好, 畢竟核心是數據庫。

四 安裝部署

4.1 prometheus安裝

  • 二進制安裝
cd /opt && wget https://github.com/prometheus/prometheus/releases/download/v2.12.0/prometheus-2.12.0.linux-amd64.tar.gz 
tar -zxf prometheus-2.12.0.linux-amd64.tar.gz
mv prometheus-2.12.0.linux-amd64 prometheus
chown root.root prometheus -R
 # 配置爲服務
cat >/usr/lib/systemd/system/prometheus.service <<EOF
[Unit]
Description=Prometheus
Documentation=https://prometheus.io/
After=network.target

[Service]
Type=simple
ExecStart=/opt/prometheus/prometheus --config.file=/opt/prometheus/prometheus.yml
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
 # 設置服務開機自啓動
systemctl enable prometheus
systemctl start prometheus
 # 直接啓動
nohup ./prometheus --config.file=prometheus.yml 2>&1 1>prometheus.log &
 # 查看服務
[root@VM_0_13_centos pushgateway]# netstat -lntup |grep prometheus
tcp6       0      0 :::9090                 :::*                    LISTEN      16655/prometheus
複製代碼
  • 源碼編譯安裝
$ go get github.com/prometheus/prometheus/cmd/...
$ prometheus --config.file=your_config.yml
 # 或者make build
$ mkdir -p $GOPATH/src/github.com/prometheus
$ cd $GOPATH/src/github.com/prometheus
$ git clone https://github.com/prometheus/prometheus.git
$ cd prometheus
$ make build
$ ./prometheus --config.file=your_config.yml
複製代碼
  • docker安裝
docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus
複製代碼

4.2 alertmanager安裝

  • 二進制安裝
cd /opt && wget -c https://github.com/prometheus/alertmanager/releases/download/v0.18.0/alertmanager-0.18.0.linux-amd64.tar.gz
tar zxf alertmanager-0.18.0.linux-amd64.tar.gz
mv alertmanager-0.18.0.linux-amd64 alertmanager
chown root.root alertmanager -R
 # 配置服務
cat >/usr/lib/systemd/system/alertmanager.service <<EOF
[Unit]
Description=Alertmanager
Documentation=https://prometheus.io/
After=network.target

[Service]
Type=simple
ExecStart=/opt/alertmanager/alertmanager --config.file=/opt/alertmanager/alertmanager.yml
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
 # 設置服務開機自啓動
systemctl enable alertmanager
systemctl start alertmanager
 # 直接啓動
nohup ./alertmanager --config.file=alertmanager.yml 2>&1 1>alertmanager.log &
 # 查看服務
[root@VM_0_13_centos pushgateway]# netstat -lntup |grep alertmanager
tcp6       0      0 :::9094                 :::*                    LISTEN      17237/alertmanager
tcp6       0      0 :::9093                 :::*                    LISTEN      17237/alertmanager
udp6       0      0 :::9094                 :::*                                17237/alertmanager
複製代碼
  • 編譯安裝
$ GO15VENDOREXPERIMENT=1 go get github.com/prometheus/alertmanager/cmd/...
# cd $GOPATH/src/github.com/prometheus/alertmanager
$ alertmanager --config.file=<your_file>
 # 手動源碼構建
$ mkdir -p $GOPATH/src/github.com/prometheus
$ cd $GOPATH/src/github.com/prometheus
$ git clone https://github.com/prometheus/alertmanager.git
$ cd alertmanager
$ make build
$ ./alertmanager --config.file=<your_file>
 # amtool構建
$ make build BINARIES=amtool
複製代碼
  • docker安裝
docker pull quay.io/prometheus/alertmanager
複製代碼

4.3 node_export安裝

利用node_export來監控主機,官方也提供了不少其餘的export能夠用來直接使用

  • 二進制安裝
cd /opt && wget -c https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
tar zxf node_exporter-0.18.1.linux-amd64.tar.gz
mv node_exporter-0.18.1.linux-amd64 node_exporter
chown root.root node_exporter -R
 # 配置服務
cat >/usr/lib/systemd/system/node_exporter.service <<EOF
[Unit]
Description=node_exporter
Documentation=https://prometheus.io/
After=network.target

[Service]
Type=simple
ExecStart=/opt/node_exporter/node_exporter
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
 # 設置服務開機自啓動
systemctl enable node_exporter
systemctl start node_exporter
 # 直接啓動
nohup ./node_exporter --config.file=node_exporter.yml 2>&1 1>node_exporter.log &
 # 查看服務
[root@VM_0_13_centos pushgateway]# netstat -lntup |grep node_export
tcp6       0      0 :::9100                 :::*                    LISTEN      4551/node_exporter
複製代碼

4.4 pushgateway

  • 安裝
cd /opt && wget -c https://github.com/prometheus/pushgateway/releases/download/v0.9.1/pushgateway-0.9.1.linux-amd64.tar.gz
tar zxf pushgateway-0.9.1.linux-amd64.tar.gz
mv pushgateway-0.9.1.linux-amd64 pushgateway
chown root.root pushgateway -R
 # 配置服務
cat >/usr/lib/systemd/system/pushgateway.service <<EOF
[Unit]
Description=pushgateway
Documentation=https://prometheus.io/
After=network.target

[Service]
Type=simple
ExecStart=/opt/pushgateway/pushgateway
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF
 # 設置服務開機自啓動
systemctl enable pushgateway
systemctl start pushgateway
 # 直接啓動
nohup ./pushgateway --config.file=node_exporter.yml 2>&1 1>node_exporter.log &
 # 查看服務
[root@VM_0_13_centos pushgateway]# netstat -lntup |grep push
tcp6       0      0 :::9091                 :::*                    LISTEN      5982/pushgateway
複製代碼
  • 查看web頁面

  • shell命令建立
echo "some_metric 3.14" | curl --data-binary @- http://localhost:9091/metrics/job/some_job
複製代碼
  • 發送複雜數據
cat <<EOF | curl --data-binary @- http://localhost:9091/metrics/job/some_job/instance/some_instance
# TYPE some_metric counter
some_metric{label="val1"} 42
# TYPE another_metric gauge
# HELP another_metric Just an example.
another_metric 2398.283
EOF
複製代碼

4.5 Grafana配置

4.5.1 grafana安裝

  • 安裝grafana
wget https://dl.grafana.com/oss/release/grafana-6.3.3-1.x86_64.rpm 
sudo yum localinstall grafana-6.3.3-1.x86_64.rpm -y

systemctl enable grafana-server.service
systemctl start grafana-server.service
# web頁面3000 登陸信息:admin/admin
 # 安裝插件
grafana-cli plugins install grafana-piechart-panel
systemctl restart grafana-server
複製代碼

4.5.2 添加數據源

添加prometheus,填寫prometheus的管理地址

  • 導入dashboard

經過https://grafana.com/grafana/dashboards中獲取

  • 配置dashboard

4.5.3 grafana告警郵件配置

  • 修改grafana配置文件,添加email配置
# 修改/etc/grafana/grafana.ini

[smtp]
enabled = true
host = smtp.163.com:465
user = 18329903316
# If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
password = xxxxxxxxxxxx
;cert_file =
;key_file =
;skip_verify = false
from_address = 18329903316@163.com
;from_name = Grafana
;ehlo_identity = dashboard.example.com
複製代碼
  • grafana web界面配置Notification channels

4.5.4 alter配置

⚠️:Template variables are not supported in alert queries,在查詢中不能使用模版語法,否則沒法建立告警

告警測試

查看告警歷史

告警觸發

五 PromQL

PromQL(Prometheus Query Language)是 Prometheus 本身開發的表達式語言,語言表現力很豐富,內置函數也不少。使用它能夠對時序數據進行篩選和聚合。

5.1 PromQL語法

5.1.1 數據類型

PromQL 表達式計算出來的值有如下幾種類型:

  • 瞬時向量 (Instant vector): 一組時序,每一個時序只有一個採樣值
  • 區間向量 (Range vector): 一組時序,每一個時序包含一段時間內的多個採樣值
  • 標量數據 (Scalar): 一個浮點數
  • 字符串 (String): 一個字符串,暫時未用

5.1.2 時序選擇器

  • 瞬時向量選擇器

    瞬時向量選擇器用來選擇一組時序在某個採樣點的採樣值。

    最簡單的狀況就是指定一個度量指標,選擇出全部屬於該度量指標的時序的當前採樣值。好比下面的表達式:

    http_requests_total
    複製代碼

    能夠經過在後面添加用大括號包圍起來的一組標籤鍵值對來對時序進行過濾。好比下面的表達式篩選出了 job 爲 prometheus,而且 group 爲 canary 的時序:

    http_requests_total{job="prometheus", group="canary"}
    複製代碼

    匹配標籤值時能夠是等於,也可使用正則表達式。總共有下面幾種匹配操做符:

    • =:徹底相等
    • !=: 不相等
    • =~: 正則表達式匹配
    • !~: 正則表達式不匹配

    下面的表達式篩選出了 environment 爲 staging 或 testing 或 development,而且 method 不是 GET 的時序:

    http_requests_total{environment=~"staging|testing|development",method!="GET"}
    複製代碼

    度量指標名可使用內部標籤 __name__ 來匹配,表達式 http_requests_total 也能夠寫成 {__name__="http_requests_total"}。表達式 {__name__=~"job:.*"} 匹配全部度量指標名稱以 job: 打頭的時序。

  • 區間向量選擇器

    區間向量選擇器相似於瞬時向量選擇器,不一樣的是它選擇的是過去一段時間的採樣值。能夠經過在瞬時向量選擇器後面添加包含在 [] 裏的時長來獲得區間向量選擇器。好比下面的表達式選出了全部度量指標爲 http_requests_total 且 job 爲 prometheus 的時序在過去 5 分鐘的採樣值。

    http_requests_total{job="prometheus"}[5m]
    複製代碼

    時長的單位能夠是下面幾種之一:

    • s:seconds
    • m:minutes
    • h:hours
    • d:days
    • w:weeks
    • y:years
  • 偏移修飾器

    前面介紹的選擇器默認都是以當前時間爲基準時間,偏移修飾器用來調整基準時間,使其往前偏移一段時間。偏移修飾器緊跟在選擇器後面,使用 offset 來指定要偏移的量。好比下面的表達式選擇度量名稱爲 http_requests_total 的全部時序在 5 分鐘前的採樣值。

    http_requests_total offset 5m
    複製代碼

    下面的表達式選擇 http_requests_total 度量指標在 1 周前的這個時間點過去 5 分鐘的採樣值。

    http_requests_total[5m] offset 1w
    複製代碼

5.2 PromQL操做符

5.2.1 二元操做符

PromQL 的二元操做符支持基本的邏輯和算術運算,包含算術類、比較類和邏輯類三大類。

  • 算術類二元操做符

    算術類二元操做符有如下幾種:

    • +:加
    • -:減
    • *:乘
    • /:除
    • %:求餘
    • ^:乘方

    算術類二元操做符能夠使用在標量與標量、向量與標量,以及向量與向量之間

    二元操做符上下文裏的向量特指瞬時向量,不包括區間向量。

    • 標量與標量之間,結果很明顯,跟一般的算術運算一致。
    • 向量與標量之間,至關於把標量跟向量裏的每個標量進行運算,這些計算結果組成了一個新的向量。
    • 向量與向量之間,會稍微麻煩一些。運算的時候首先會爲左邊向量裏的每個元素在右邊向量裏去尋找一個匹配元素(匹配規則後面會講),而後對這兩個匹配元素執行計算,這樣每對匹配元素的計算結果組成了一個新的向量。若是沒有找到匹配元素,則該元素丟棄。
  • 比較類二元操做符

    比較類二元操做符有如下幾種:

    • == (equal)
    • != (not-equal)
    • > (greater-than)
    • < (less-than)
    • >= (greater-or-equal)
    • <= (less-or-equal)

    比較類二元操做符一樣能夠使用在標量與標量、向量與標量,以及向量與向量之間。默認執行的是過濾,也就是保留值。能夠經過在運算符後面跟 bool 修飾符來使得返回值 0 和 1,而不是過濾。

    • 標量與標量之間,必須跟 bool 修飾符,所以結果只多是 0(false) 或 1(true)。
    • 向量與標量之間,至關於把向量裏的每個標量跟標量進行比較,結果爲真則保留,不然丟棄。若是後面跟了 bool 修飾符,則結果分別爲 1 和 0。
    • 向量與向量之間,運算過程相似於算術類操做符,只不過若是比較結果爲真則保留左邊的值(包括度量指標和標籤這些屬性),不然丟棄,沒找到匹配也是丟棄。若是後面跟了 bool 修飾符,則保留和丟棄時結果相應爲 1 和 0。
  • 邏輯類二元操做符

    邏輯操做符僅用於向量與向量之間。

    • and:交集
    • or:合集
    • unless:補集

    具體運算規則以下:

    • vector1 and vector2 的結果由在 vector2 裏有匹配(標籤鍵值對組合相同)元素的 vector1 裏的元素組成。
    • vector1 or vector2 的結果由全部 vector1 裏的元素加上在 vector1 裏沒有匹配(標籤鍵值對組合相同)元素的 vector2 裏的元素組成。
    • vector1 unless vector2 的結果由在 vector2 裏沒有匹配(標籤鍵值對組合相同)元素的 vector1 裏的元素組成。
  • 二元操做符優先級

    PromQL 的各種二元操做符運算優先級以下:

    1. ^
    2. *, /, %
    3. +, -
    4. ==, !=, <=, <, >=, >
    5. and, unless
    6. or

5.2.2 向量匹配

前面算術類和比較類操做符都須要在向量之間進行匹配。共有兩種匹配類型,one-to-onemany-to-one / one-to-many

  • One-to-one 向量匹配

    相同則爲匹配,而且只會有一個匹配元素。可使用 ignoring 關鍵詞來忽略不參與匹配的標籤,或者使用 on關鍵詞來指定要參與匹配的標籤。語法以下:

    <vector expr> <bin-op> ignoring(<label list>) <vector expr>
    <vector expr> <bin-op> on(<label list>) <vector expr>
    複製代碼

    好比對於下面的輸入:

    method_code:http_errors:rate5m{method="get", code="500"}  24
    method_code:http_errors:rate5m{method="get", code="404"}  30
    method_code:http_errors:rate5m{method="put", code="501"}  3
    method_code:http_errors:rate5m{method="post", code="500"} 6
    method_code:http_errors:rate5m{method="post", code="404"} 21
    
    method:http_requests:rate5m{method="get"}  600
    method:http_requests:rate5m{method="del"}  34
    method:http_requests:rate5m{method="post"} 120
    複製代碼

    執行下面的查詢:

    method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
    複製代碼

    獲得的結果爲:

    {method="get"}  0.04            //  24 / 600
    {method="post"} 0.05            //   6 / 120
    複製代碼

    也就是每一種 method 裏 code 爲 500 的請求數佔總數的百分比。因爲 method 爲 put 和 del 的沒有匹配元素因此沒有出如今結果裏。

  • Many-to-one / one-to-many 向量匹配

    這種匹配模式下,某一邊會有多個元素跟另外一邊的元素匹配。這時就須要使用 group_leftgroup_right 組修飾符來指明哪邊匹配元素較多,左邊多則用 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>
    複製代碼

    組修飾符只適用於算術類和比較類操做符。

    對於前面的輸入,執行下面的查詢:

    method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
    複製代碼

    將獲得下面的結果:

    {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
    複製代碼

    也就是每種 method 的每種 code 錯誤次數佔每種 method 請求數的比例。這裏匹配的時候 ignoring 了 code,才使得兩邊能夠造成 Many-to-one 形式的匹配。因爲左邊多,因此須要使用 group_left 來指明。

    Many-to-one / one-to-many 過於高級和複雜,要儘可能避免使用。不少時候經過 ignoring 就能夠解決問題。

5.2.3 聚合操做符

PromQL 的聚合操做符用來將向量裏的元素聚合得更少。總共有下面這些聚合操做符:

  • sum:求和
  • min:最小值
  • max:最大值
  • avg:平均值
  • stddev:標準差
  • stdvar:方差
  • count:元素個數
  • count_values:等於某值的元素個數
  • bottomk:最小的 k 個元素
  • topk:最大的 k 個元素
  • quantile:分位數

聚合操做符語法以下:

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
複製代碼

其中 without 用來指定不須要保留的標籤(也就是這些標籤的多個值會被聚合),而 by 正好相反,用來指定須要保留的標籤(也就是按這些標籤來聚合)。

下面來看幾個示例:

sum(http_requests_total) without (instance)
複製代碼

http_requests_total 度量指標帶有 application、instance 和 group 三個標籤。上面的表達式會獲得每一個 application 的每一個 group 在全部 instance 上的請求總數。效果等同於下面的表達式:

sum(http_requests_total) by (application, group)
複製代碼

下面的表達式能夠獲得全部 application 的全部 group 的全部 instance 的請求總數。

sum(http_requests_total)
複製代碼

5.3 函數

Prometheus 內置了一些函數來輔助計算,下面介紹一些典型的,完整的列表請參考 官方文檔

  • abs():絕對值
  • sqrt():平方根
  • exp():指數計算
  • ln():天然對數
  • ceil():向上取整
  • floor():向下取整
  • round():四捨五入取整
  • delta():計算區間向量裏每個時序第一個和最後一個的差值
  • sort():排序

六 配置告警規則

將報警集成到睿象雲

6.1 prometheus集成altermanager

# 編輯prometheus.yml

alerting:
  alertmanagers:
  - static_configs:
    - targets:
       - 'localhost:9093'
       
rule_files:
  - "onealter.yml"
複製代碼

6.2 編寫rule_files規則文件

# 編寫onealter.yml
groups:
  - name: test-rule
    rules:
      - alert: 節點內存使用量
        expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes+node_memory_Buffers_bytes+node_memory_Cached_bytes )) / node_memory_MemTotal_bytes * 100 > 40
        for: 1m
        labels:
          user: prometheus
        annotations:
          summary: "{{$labels.instance}}:內存超過40%"
          description: "{{$labels.instance}}:內存超過40%"
複製代碼

6.3 編輯altermanager.yml配置webhook回調

# 編輯

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 1h
  receiver: 'team-X-pager'
receivers:
- name: 'team-X-pager'
  webhook_configs:
  - url: 'http://api.aiops.com/alert/api/event/prometheus/f307ded7-9a96-4e34-101d-dfc421a8743a'
    send_resolved: true
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']
複製代碼

6.4 查看alter告警

參考連接

相關文章
相關標籤/搜索