文章轉載自:https://www.cnblogs.com/gered/p/13496950.html
警報一直是整個監控系統中的重要組成部分,Prometheus監控系統中,采集與警報是分離的。
報警規則在 Prometheus 定義,警報規則觸發以后,才會將信息轉發到給獨立的組件Alertmanager ,經過 Alertmanager對警報的信息處理后,最終通過接收器發送給指定用戶,另外在 Alertmanager 中沒有通知組的概念,只能自己對軟件重新Coding,或者使用第三方插件來實現。
注意,這個通知組不是Alertmanager中的group概念,下面會詳細講 Group ,不要混淆哦。
前面已經介紹過一些關於 Alertmanager 知識點,本章開始針通過安裝 Alertmanager 組件,對配置文件做詳細說明,同時介紹 Prometheus 的警報規則的定義,最后使用Email、Wechat(Robot)、Dingtalk(webhook)來接受警報通知。
Alertmanager工作機制
在Prometheus生態架構里,警報是由獨立的倆部分組成,可以通過上圖很清晰的了解到 Prometheus 的警報工作機制。
其中 Prometheus 與 Alertmanager 是分離的倆個組件。
使用Prometheus Server端通過靜態或者動態配置去拉取 pull 部署在k8s或雲主機上的各種類別的監控指標數據,然后基於 PromQL 對這些已經存儲在本地存儲 HDD/SSD 的 TSDB 中的指標定義閾值警報規則 Rules 。Prometheus會根據配置的參數周期性的對警報規則進行計算,如果滿足警報條件,生產一條警報信息,將其推送到 Alertmanager 組件,Alertmanager 收到警報信息之后,會對警告信息進行處理,進行 分組 Group 並將它們通過定義好的路由 Routing 規則轉到 正確的接收器 receiver,比如 Email Slack 釘釘、企業微信 Robot(webhook) 企業微信 等,最終異常事件 Warning、Error通知給定義好的接收人,其中如釘釘是基於第三方通知來實現的,對於通知人定義是在釘釘的第三方組件中配置。
在 Prometheus 中,不僅僅可以對單條警報進行命名通過 PromQL定義規則,更多時候是對相關的多條警報進行分組后統一定義。這些定義會在后面說明與其管理方法。下面開始把 Alertmanager 中的分組 Grouping 、抑制 Inhibition、延遲 Silences
核心特性進行介紹,便於大家系統性的學習與理解。
AlertManager的三個概念
分組(Grouping)
Grouping
是 Alertmanager 把同類型的警報進行分組,合並多條警報到一個通知中。在生產環境中,特別是雲環境下的業務之間密集耦合時,若出現多台 Instance 故障,可能會導致成千上百條警報觸發。在這種情況下使用分組機制, 可以把這些被觸發的警報合並為一個警報進行通知,從而避免瞬間突發性的接受大量警報通知,使得管理員無法對問題進行快速定位。
舉個例子,在Kubernetes集群中,運行着重量級規模的實例,即便是集群中持續很小一段時間的網絡延遲或者延遲導致網絡抖動,也會引發大量類似服務應用無法連接 DB
的故障。如果在警報規則中定義每一個應用實例都發送警報,那么到最后的結果就是 會有大量的警報信息發送給 Alertmanager 。
作為運維組或者相關業務組的開發人員,可能更關心的是在一個通知中就可以快速查看到哪些服務實例被本次故障影響了。為此,我們對服務所在集群或者服務警報名稱的維度進行分組配置,把警報匯總成一條通知時,就不會受到警報信息的頻繁發送影響了。
抑制(Inhibition)
Inhibition
是 當某條警報已經發送,停止重復發送由此警報引發的其他異常或故障的警報機制。在生產環境中,IDC托管機櫃中,若每一個機櫃接入層僅僅是單台交換機,那么該機櫃接入交換機故障會造成機櫃中服務器非 up
狀態警報。再有服務器上部署的應用服務不可訪問也會觸發警報。
這時候,可以通過在 Alertmanager 配置忽略由於交換機故障而造成的此機櫃中的所有服務器及其應用不可達而產生的警報。
在我們的災備體系中,當原有集群故障宕機業務徹底無法訪問的時候,會把用戶流量切換到備份集群中,這樣為故障集群及其提供的各個微服務狀態發送警報機會失去了意義,此時, Alertmanager 的抑制特性就可以在一定程度上避免管理員收到過多無用的警報通知。
靜默(Silences
)
Silences
提供了一個簡單的機制,根據標簽快速對警報進行靜默處理;對傳進來的警報進行匹配檢查,如果接受到警報符合靜默的配置,Alertmanager 則不會發送警報通知。
以上除了分組、抑制是在 Alertmanager 配置文件中配置,靜默是需要在 WEB UI 界面中設置臨時屏蔽指定的警報通知。
以上的概念需要好好理解,這樣才可以輕松的在監控系統設計的時候針對警報設計的一些場景自行調整。
安裝Alertmanager
二進制安裝
用 Alertmanager 的二進制安裝,以 systemd 管理啟動。
## 創建相關目錄
mkdir -p /data/alertmanager/{bin,conf,logs,data,templates}
## 下載二進制包
wget https://github.com/prometheus/alertmanager/releases/download/v0.21.0/alertmanager-0.21.0.linux-amd64.tar.gz
tar xvf alertmanager-0.21.0.linux-amd64.tar.gz
mv alertmanager-0.21.0.linux-amd64/{alertmanager,amtool} /data/alertmanager/bin/
mv alertmanager-0.21.0.linux-amd64/alertmanager.yml /data/alertmanager/conf/
# 目錄結構
/data/alertmanager/
├── bin
│ ├── alertmanager
│ └── amtool
├── conf
│ └── alertmanager.yml
├── data
├── logs
└── templates
## 加入systemd啟動腳本
cat <<EOF >/lib/systemd/system/alertmanager.service
[Unit]
Description=alertmanager
Documentation=https://prometheus.io/
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=prometheus
ExecStart=/data/alertmanager/bin/alertmanager --storage.path="/data/alertmanager/data/" \
--config.file=/usr/local/alertmanager/alertmanager.yml \
--web.external-url=http://192.168.1.220 # 此處可以寫域名,需要做proxy。
Restart=always
RestartSec=1
# Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
## 啟動
systemctl enable alertmanager
systemctl start alertmanager
Alertmanager 參數
參數 | 描述 |
---|---|
--config.file="alertmanager.yml" |
指定Alertmanager配置文件路徑 |
--storage.path="data/" |
Alertmanager的數據存放目錄 |
--data.retention=120h |
歷史數據保留時間,默認為120h |
--alerts.gc-interval=30m |
警報gc之間的間隔 |
--web.external-url=WEB.EXTERNAL-URL |
外部可訪問的Alertmanager的URL(例如Alertmanager是通過nginx反向代理) |
--web.route-prefix=WEB.ROUTE-PREFIX |
wen訪問內部路由路徑,默認是 --web.external-url |
--web.listen-address=":9093" |
監聽端口,可以隨意修改 |
--web.get-concurrency=0 |
並發處理的最大GET請求數,默認為0 |
--web.timeout=0 |
web請求超時時間 |
--cluster.listen-address="0.0.0.0:9094" |
集群的監聽端口地址。設置為空字符串禁用HA模式 |
--cluster.advertise-address=CLUSTER.ADVERTISE-ADDRESS |
配置集群通知地址 |
--cluster.gossip-interval=200ms |
發送條消息之間的間隔,可以以增加帶寬為代價更快地跨集群傳播。 |
--cluster.peer-timeout=15s |
在同級之間等待發送通知的時間 |
... | ... |
--log.level=info |
自定義消息格式 [debug, info, warn, error] |
--log.format=logfmt |
日志消息的輸出格式: [logfmt, json] |
--version |
顯示版本號 |
Alertmanager配置詳解
案例演示
## Alertmanager 配置文件
global:
resolve_timeout: 5m
# smtp配置
smtp_from: "123456789@qq.com"
smtp_smarthost: 'smtp.qq.com:465'
smtp_auth_username: "123456789@qq.com"
smtp_auth_password: "auth_pass"
smtp_require_tls: true
# email、企業微信的模板配置存放位置,釘釘的模板會單獨講如果配置。
templates:
- '/data/alertmanager/templates/*.tmpl'
# 路由分組
route:
receiver: ops
group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。
group_interval: 5m # 如果組內內容不變化,合並為一條警報信息,5m后發送。
repeat_interval: 24h # 發送報警間隔,如果指定時間內沒有修復,則重新發送報警。
group_by: [alertname] # 報警分組
routes:
- match:
team: operations
group_by: [env,dc]
receiver: 'ops'
- match_re:
service: nginx|apache
receiver: 'web'
- match_re:
service: hbase|spark
receiver: 'hadoop'
- match_re:
service: mysql|mongodb
receiver: 'db'
# 接收器
# 抑制測試配置
- receiver: ops
group_wait: 10s
match:
status: 'High'
# ops
- receiver: ops # 路由和標簽,根據match來指定發送目標,如果 rule的lable 包含 alertname, 使用 ops 來發送
group_wait: 10s
match:
team: operations
# web
- receiver: db # 路由和標簽,根據match來指定發送目標,如果 rule的lable 包含 alertname, 使用 db 來發送
group_wait: 10s
match:
team: db
# 接收器指定發送人以及發送渠道
receivers:
# ops分組的定義
- name: ops
email_configs:
- to: '9935226@qq.com,10000@qq.com'
send_resolved: true
headers:
subject: "[operations] 報警郵件"
from: "警報中心"
to: "小煜狼皇"
# 釘釘配置
webhook_configs:
- url: http://localhost:8070/dingtalk/ops/send
# 企業微信配置
wechat_configs:
- corp_id: 'ww5421dksajhdasjkhj'
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
send_resolved: true
to_party: '2'
agent_id: '1000002'
api_secret: 'Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj'
# web
- name: web
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[web] 報警郵件"} # 接收郵件的標題
webhook_configs:
- url: http://localhost:8070/dingtalk/web/send
- url: http://localhost:8070/dingtalk/ops/send
# db
- name: db
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[db] 報警郵件"} # 接收郵件的標題
webhook_configs:
- url: http://localhost:8070/dingtalk/db/send
- url: http://localhost:8070/dingtalk/ops/send
# hadoop
- name: hadoop
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[hadoop] 報警郵件"} # 接收郵件的標題
webhook_configs:
- url: http://localhost:8070/dingtalk/hadoop/send
- url: http://localhost:8070/dingtalk/ops/send
# 抑制器配置
inhibit_rules: # 抑制規則
- source_match: # 源標簽警報觸發時抑制含有目標標簽的警報,在當前警報匹配 status: 'High'
status: 'High' # 此處的抑制匹配一定在最上面的route中配置不然,會提示找不key。
target_match:
status: 'Warning' # 目標標簽值正則匹配,可以是正則表達式如: ".*MySQL.*"
equal: ['alertname','operations', 'instance'] # 確保這個配置下的標簽內容相同才會抑制,也就是說警報中必須有這三個標簽值才會被抑制。
global
即為全局設置,在 Alertmanager 配置文件中,只要全局設置配置了的選項,全部為公共設置,可以讓其他設置繼承,作為默認值,可以子參數中覆蓋其設置。其中 resolve_timeout 用於設置處理超時時間,也是生命警報狀態為解決的時間,
這個時間會直接影響到警報恢復的通知時間,需要自行結合實際生產場景來設置主機的恢復時間,默認是5分鍾。在全局設置中可以設置smtp服務,同時也支持slack、victorops、pagerduty等,在這里只講我們常用的Email,釘釘,企業微信,
同時也可以自己使用go語言開發的gubot進行二次開發,對接自定義webhook通知源。
template
警報模板可以自定義通知的信息格式,以及其包含的對應警報指標數據,可以自定義Email、企業微信的模板,配置指定的存放位置,對於釘釘的模板會單獨講如何配置,這里的模板是指的發送的通知源信息格式模板,比如Email,企業微信。
route
警報路由模塊描述了在收到 Prometheus 生成的警報后,將警報信息發送給接收器 receiver 指定的目標地址規則。 Alertmanager 對傳入的警報信息進行處理,根據所定義的規則與配置進行匹配。對於路由可以理解為樹狀結構,
設置的第一個route是跟節點,往下的就是包含的子節點,每個警報傳進來以后,會從配置的跟節點路由進入路由樹,按照深度優先從左向右遍歷匹配,當匹配的節點后停止,進行警報處理。
參數描述
參數 | 描述 | |
---|---|---|
receiver: <string> |
發送警報的接收器名稱 | |
group_by: ['label_name1,...'] |
根據 prometheus 的 lables 進行報警分組,這些警報會合並為一個通知發送給接收器,也就是警報分組。 | |
match: [ <label_name>: <labelvalue>,...] |
通過此設置來判斷當前警報中是否有標簽的labelname,等同於labelvalue。 | |
match_re: [<label_name>: <regex>,...] |
通過正則表達式進行警報配置 | |
group_wait: [<duration>] | default=30s |
設置從接受警報到發送的等待時間,若在等待時間中group接收到新的警報信息,這些警報會合並為一條發送。 | |
group_interval: [<duration>] | default=5m |
此設置控制的是 group 之間發送警報通知的間隔時間。 |
|
repeat_interval: [<duration>] | default=4h |
此設置控制的是警報發送成功以后,沒有對警報做解決操作的話,狀態 Firing 沒有變成 Inactive 或者 Pending ,會再次發送警報的的間隔時間。 |
|
routes: - <route> ... |
子路由的匹配設置 |
route 路由匹配規則
route:
receiver: admin # 默認的接收器名稱
group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。
group_interval: 5m # 如果組內內容不變化,5m后發送。
repeat_interval: 24h # 發送報警間隔,如果指定時間內沒有修復,則重新發送報警
group_by: [alertname,cluster] # 報警分組,根據 prometheus 的 lables 進行報警分組,這些警報會合並為一個通知發送給接收器,也就是警報分組。
routes:
- match:
team: ops
group_by: [env,dc]
receiver: 'ops'
- match_re:
service: nginx|apache
receiver: 'web'
- match_re:
service: mysql|mongodb
receiver: 'db'
- match_re:
service: hbase|spark
receiver: 'hadoop'
在以上的例子中,默認的警報組全部發送給 admin ,且根據路由按照 alertname cluster 進行警報分組。在子路由中的若匹配警報中的標簽 team 的值為 ops,Alertmanager 會按照標簽 env dc 進行警報分組然后發送給接收器 receiver ops配置的警報通知源。
繼續匹配的操作是對 service 標簽進行匹配,並且配到了 nginx redis mongodb 的值,就會向接收器 receiver web配置的警報通知源發送警報信息。
對這種匹配驗證操作灰常考究個人的邏輯思維能力,這不是人干的事情呀~因此,Prometheus發布了一個 Routing tree editor,
用於檢測Alertmanager的配置文件結構配置信息,然后調試。使用方法很簡單,就是把 alertmanager.yml 的配置信心復制到這個站點,然后點擊 Draw Routing Tree 按鈕生成路由結構樹,
然后在 Match Label Set 前面輸入以 {
receiver 接收器
接受器是一個統稱,每個 receiver 都有需要設置一個全局唯一的名稱,並且對應一個或者多個通知方式,包括email、微信、Slack、釘釘等。
官方現在滿足的配置是:
name: <string>
email_config:
[ - <config> ]
hipchat_configs: #此模塊配置已經被移除了
[ <config> ]
pagerduty_configs:
[ <config> ]
pushover_configs:
[ <config> ]
slack_configs:
[ <config> ]
opsgenie_configs:
[ <config> ]
webhook_configs:
[ <config> ]
victorops_configs:
[ <config> ]
webchat_configs:
[ <config> ]
可以看到Alertmanager提供了很多種接收器的通知配置,我們可以使用webhook接收器來定義通知集成,支持用戶自己定義編寫。
inhibit_rules 抑制器
inhibit_rules 模塊中設置警報抑制功能,可以指定在特定條件下需要忽略的警報條件。可以使用此選項設置首選,比如優先處理某些警報,如果同一組中的警報同時發生,則忽略其他警報。
合理使用 inhibit_rules ,可以減少頻發發送沒有意義的警報的產生。
inhibit_rules 配置信息:
trget_match:
[ <label_name>: <labelvalue>,... ]
trget_match_re:
[ <label_name>: <labelvalue>,... ]
source_match:
[ <label_name>: <labelvalue>,... ]
source_match_re:
[ <label_name>: <labelvalue>,... ]
[ equal: '[' <lable_name>, ...]']
inhibit_rules: # 抑制規則
- source_match: # 源標簽警報觸發時抑制含有目標標簽的警報,在當前警報匹配 status: 'High'
status: 'High' # 此處的抑制匹配一定在最上面的route中配置不然,會提示找不key。
target_match:
status: 'Warning' # 目標標簽值正則匹配,可以是正則表達式如: ".*MySQL.*"
equal: ['alertname','operations', 'instance'] # 確保這個配置下的標簽內容相同才會抑制,也就是說警報中必須有這三個標簽值才會被抑制。
以上示例是指 如果匹配 equal 中的抑制的標簽值,觸發了包含 equal 中的標簽值的 status: 'High' 警報 ,則不發送含包含 equal 中的標簽值的 status: 'Warning' 標簽的警報。
這里盡量避免 source_match 與 target_match 之間的重疊,否則很難做到理解與維護,同時建議謹慎使用此功能。使用基於症狀的警報時,警報之間很少需要相互依賴。
警報通知接收器
前面一直是在Web UI 查看警報信息,現在開始使用接收器與Alertmanager集成,發送警報信息到 Email、企業微信、釘釘機器人,對於警報要求比較高的同學,可以根據下面提到的開源組件 【PrometheusAlert全家桶】 配置飛書、短信、語音電話等警報。
Alertmanager默認支持配置Email,也是最普通的方式,在Alertmanager組件中內置了SMTP協議。直接可以把前面的Alertmanager.yml中的SMTP部分截取出來,然后進行調整與配置
global:
resolve_timeout: 5m
# smtp配置
smtp_from: "1234567890@qq.com" # 發送郵件主題
smtp_smarthost: 'smtp.qq.com:465' # 郵箱服務器的SMTP主機配置
smtp_auth_username: "1234567890@qq.com" # 登錄用戶名
smtp_auth_password: "auth_pass" # 此處的auth password是郵箱的第三方登錄授權密碼,而非用戶密碼,盡量用QQ來測試。
smtp_require_tls: false # 有些郵箱需要開啟此配置,這里使用的是163郵箱,僅做測試,不需要開啟此功能。
route:
receiver: ops
group_wait: 30s # 在組內等待所配置的時間,如果同組內,30秒內出現相同報警,在一個組內出現。
group_interval: 5m # 如果組內內容不變化,合並為一條警報信息,5m后發送。
repeat_interval: 24h # 發送報警間隔,如果指定時間內沒有修復,則重新發送報警。
group_by: [alertname] # 報警分組
routes:
- match:
team: operations
group_by: [env,dc]
receiver: 'ops'
- receiver: ops # 路由和標簽,根據match來指定發送目標,如果 rule的lable 包含 alertname, 使用 ops 來發送
group_wait: 10s
match:
team: operations
# 接收器指定發送人以及發送渠道
receivers:
# ops分組的定義
- name: ops
email_configs:
- to: '9935226@qq.com,xxxxx@qq.com' # 如果想發送多個人就以 ','做分割,寫多個郵件人即可。
send_resolved: true
headers:
from: "警報中心"
subject: "[operations] 報警郵件"
to: "小煜狼皇"
配置完成后,直接重啟Alertmanager組件,使配置生效,然后使用前面內存閾值觸發一次警報來看下發送結果。
企業微信
首先你要具有企業微信管理員的權限,如果沒有可以自己注冊一個,進行測試,我這里有自行注冊的企業微信
第一步登錄進入以后,在應用管理中新建應用。
第二步,創建應用,信息填寫如下,上傳應用logo隨意。
創建成功以后如下圖。
這時候需要把 AgentId 和 Secret 記錄下來,對於你的這種Secret信息,最好管理好,我的用過就會刪除,所以不用擔心安全隱患。
第三步,現在我們來用新建的企業微信應用在Alertmanager配置,可以配置全局,也可以對單獨需要發送的接收器,因為警報需要分級,所以需要單獨處理,在這里使用的的單獨的配置,需要知道 企業ID ,以及 部門ID 。
部門ID 通過通訊錄獲取
這時候我們重啟Alertmanager,然后使用之前的方式來觸發模擬警報,看看發送是不是已經沒有問題了,這時我們的企業微信中、Email都可以收到警報了,這里的警報已經被我用模塊處理過了。可讀性會更高。
cat wechat.tmpl
## wechat模板
{{ define "wechat.default.message" }}
{{ if gt (len .Alerts.Firing) 0 -}}
Alerts Firing:
{{ range .Alerts }}
警報級別:{{ .Labels.status }}
警報類型:{{ .Labels.alertname }}
故障主機: {{ .Labels.instance }}
警報主題: {{ .Annotations.summary }}
警報詳情: {{ .Annotations.description }}
⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- end }}
{{- end }}
{{ if gt (len .Alerts.Resolved) 0 -}}
Alerts Resolved:
{{ range .Alerts }}
警報級別:{{ .Labels.status }}
警報類型:{{ .Labels.alertname }}
故障主機: {{ .Labels.instance }}
警報主題: {{ .Annotations.summary }}
警報詳情: {{ .Annotations.description }}
⏱ : {{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
⏲ : {{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}
{{- end }}
{{- end }}
{{- end }}
Firing警報:
下面是Resolve的警報:
釘釘機器人(Webhook)
首先需要在釘釘創建機器人,然后在白名單中添加關鍵字信息與ip限制等安全設置,這個只要你有群,你就可以在群里面建,非常簡單,這里就不做演示了
先把Prometheus-webhook-Dingtalk組件裝好。
mkdir -p /etc/prometheus-webhook-dingtalk/template/
cd /etc/prometheus-webhook-dingtalk/
wget https://github.com/timonwong/prometheus-webhook-dingtalk/releases/download/v1.4.0/prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
tar xf prometheus-webhook-dingtalk-1.4.0.linux-amd64.tar.gz
mv prometheus-webhook-dingtalk-1.4.0.linux-amd64/* /etc/prometheus-webhook-dingtalk/
mv prometheus-webhook-dingtalk /bin/
cat <<EOF> /lib/systemd/system/prometheus-webhook-dingtalk.service
[Unit]
Description=prometheus-webhook-dingding
Documentation=https://prometheus.io/
After=network.target
[Service]
Type=simple
User=prometheus
ExecStart=/bin/prometheus-webhook-dingtalk --web.listen-address=":8070" --web.enable-ui --config.file="/etc/prometheus-webhook-dingtalk/config.yml"
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF
## 啟動服務
systemctl enable prometheus-webhook-dingtalk.service
systemctl start prometheus-webhook-dingtalk.service
配置文件
## Request timeout
# timeout: 5s
## Customizable templates path
## Customizable templates path
templates:
# - contrib/templates/legacy/template.tmpl
# 自定義模板路徑
- /etc/prometheus-webhook-dingtalk/template/default.tmpl
## 你還可以使用' default_message '覆蓋默認模板
## 下面的示例使用v0.3.0中的“legacy”模板
# default_message:
# title: '{{ template "legacy.title" . }}'
# text: '{{ template "legacy.content" . }}'
## Targets, previously was known as "profiles"
# 定義的webhook,釘釘創建的webhook token
targets:
# 如果有多個分組就可以在這里定義多個接口
ops:
url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2322222222222222222222222
web:
url: https://oapi.dingtalk.com/robot/send?access_token=a4feed2325c1333333333333333333333
定義模板:
cd /etc/prometheus-webhook-dingtalk/template
cat default.tmpl
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver }}{{ end }}
{{ define "__text_alert_list" }}{{ range . }}
**Labels**
{{ range .Labels.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Annotations**
{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})
{{ end }}{{ end }}
{{/* Firing */}}
{{ define "default.__text_alert_list" }}{{ range . }}
**Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
**Summary:** {{ .Annotations.summary }}
**Description:** {{ .Annotations.description }}
**Graph:** [📈 ]({{ .GeneratorURL }})
**Details:**
{{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}{{ end }}
{{ end }}{{ end }}
{{/* Resolved */}}
{{ define "default.__text_resolved_list" }}{{ range . }}
**Trigger Time:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
**Resolved Time:** {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }}
**Summary:** {{ .Annotations.summary }}
**Graph:** [📈 ]({{ .GeneratorURL }})
**Details:**
{{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}{{ end }}
{{ end }}{{ end }}
{{/* Default */}}
{{ define "default.title" }}{{ template "__subject" . }}{{ end }}
{{ define "default.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ if gt (len .Alerts.Firing) 0 -}}

**Alerts Firing**
{{ template "default.__text_alert_list" .Alerts.Firing }}
{{- end }}
{{ if gt (len .Alerts.Resolved) 0 -}}

**Alerts Resolved**
{{ template "default.__text_resolved_list" .Alerts.Resolved }}
{{- end }}
{{- end }}
{{/* Legacy */}}
{{ define "legacy.title" }}{{ template "__subject" . }}{{ end }}
{{ define "legacy.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ template "__text_alert_list" .Alerts.Firing }}
{{- end }}
{{/* Following names for compatibility */}}
{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
在Alertmanager中配置警報
# 接收器指定發送人以及發送渠道
receivers:
# ops分組的定義
- name: ops
email_configs:
- to: '9935226@qq.com,10000@qq.com'
send_resolved: true
headers: { Subject: "[operations] 報警郵件"} # 接收郵件的標題
# 釘釘配置
webhook_configs:
- url: http://localhost:8070/dingtalk/ops/send # 這里是在釘釘開源組件中的接口,如果單獨定義的receiver需要對應你的分組與釘釘機器人的webhook token
# 企業微信配置
wechat_configs:
- corp_id: 'ww5421dksajhdasjkhj'
api_url: 'https://qyapi.weixin.qq.com/cgi-bin/'
send_resolved: true
to_party: '2'
agent_id: '1000002'
api_secret: 'Tm1kkEE3RGqVhv5hO-khdakjsdkjsahjkdksahjkdsahkj'
# web
- name: web
email_configs:
- to: '9935226@qq.com'
send_resolved: true
headers: { Subject: "[web] 報警郵件"} # 接收郵件的標題
webhook_configs:
- url: http://localhost:8070/dingtalk/web/send
繼續使用上面的觸發模擬警報,此時會同時讓三個警報都接受到警報信息,我們這里只是為了調試,往往一個警報通知就可以滿足需求了,對於重要業務還是需要使用電話以及短信提醒。
釘釘Firing警報:
釘釘Resolve警報:
警報通知模板
Prometheus 創建警報轉發給 Alertmanager,Alertmanager會根據不同的 Label 向不同的 Receiver 發送警報通知,如Email、釘釘、企業微信、飛書、短信等等。所有 Receiver都一個接收模板,然后通過模板格式化以后發送警報信息給 Receiver。
Alertmanager 自帶的模板是基於 Go 語言的 template 模板,用戶可以根據自己的需求去定義自己需要的模板,上面我給出的模板已經足夠大家的基礎使用了。
下面介紹下通常自定義模板中會需要用到的一些參數說明
名稱 | 數據類型 | 描述 |
---|---|---|
Receiver |
string | 接受警報通知的接收器名稱 |
Status |
string | 警報狀態,例如:Firing或Resolved的通知 |
Alert |
Alert | 警報通知的真實內容,警報中的所有列表 |
GroupLables |
KV | 包含警報通知的組標簽 |
CommandLabels |
KV | 所有警報的公共標簽,包含GroupLabels的所有標簽 |
CommandAnnotations |
KV | 注釋,比如自定義的一些字符串 |
ExternalURL |
string | 警報信息中的Alertmanager地址 |
上面說的KV類型是一組使用不標示標簽與注釋的Key/Value字符串對,可以在Alertmanager中的默認模板中看到其定義。 default.tmpl
其中郵件中所顯示的 View In AlertManager ,Receiver 與 ExternalURL的定義其實就是模板中的 .ExternalURL 與 .Receiver 。
{{ define "__alertmanager" }}AlertManager{{ end }}
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver | urlquery }}{{ end }}
在收到的郵箱警報中可以看到 View In AlertManager 的鏈接地址是:http://192.168.1.220:19093/#/alerts?receiver=ops 。
對於Alert的類型,警報列表的字段還包含了如下參數與定義、描述
名稱 | 數據類型 | 描述 |
---|---|---|
Status |
string | 定義警報狀態是已經解決或處於觸發狀態 |
Label |
KV | 包含警報中的標簽 |
Annotations |
KV | 警報的一組注釋 |
StartsAt |
time.Time | 警報觸發時間 |
EndsAt |
time.Time | 警報結束時間,只在警報結束的時間時設置 |
GeneratorURL |
string | 警報規則的連接URL,也就是Prometheus中的Rules查詢地址 |
對於警報中的通知模板首先要熟悉go語言的template語法以及HTML簡單的基礎知識,然后把上面相關的元數據的一些信息了解清楚,就可以自己調整模板了,如果你實在懶的改,我調整好的模板可以直接拿去用,把對應的指標、標簽名字改一下就可以用了。
以下是我自己修改了一下的模板警報格式,大家可以看看,這個是通過官方的 default.tmpl 修改的。
開源警報組件推薦
- Prometheus-Webhook-Dingtalk
一個開源的第三方警報插件,針對釘釘機器人 webhook 做集成,Go語言編寫,現在迭代的已經很不錯了,可能有一些功能還是有些限制,比如針對 Markdown @某個人無法實現,原因是因釘釘自身API沒有支持這個功能。
- Alertmanager-wechatrobot-webhook
這個開源組件是將Alertmanger Webhook 消息轉換為可以接收消息的企業微信機器人,也是go語言編寫,Alertmanager 默認已經集成企業微信配置,如果有特殊需求,需要使用企業微信機器人的可以看看這個。
- PrometheusAlert全家桶
如果有對短信、電話警報等其他需求的同學,推薦這個開源警報組件,Go語言編寫,Web框架是 Beego ,支持將收到的這些消息發送到釘釘,微信,飛書,騰訊短信,騰訊電話,阿里雲短信,阿里雲電話,華為短信,容聯雲電話等