在某些情況下除了Alertmanager已經內置的集中告警通知方式以外,對於不同的用戶和組織而言還需要一些自定義的告知方式支持。通過Alertmanager提供的webhook支持可以輕松實現這一類的擴展。除了用於支持額外的通知方式,webhook還可以與其他第三方系統集成實現運維自動化,或者彈性伸縮等。
在Alertmanager中可以使用如下配置定義基於webhook的告警接收器receiver。一個receiver可以對應一組webhook配置。
1 2 3
|
name: <string> webhook_configs: [ - <webhook_config>, ... ]
|
每一項webhook_config的具體配置格式如下:
send_resolved用於指定是否在告警消除時發送回執消息。url則是用於接收webhook請求的地址。http_configs則是在需要對請求進行SSL配置時使用。
當用戶定義webhook用於接收告警信息后,當告警被觸發時,Alertmanager會按照以下格式向這些url地址發送HTTP Post請求,請求內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
{ "version": "4", "groupKey": <string>, // key identifying the group of alerts (e.g. to deduplicate) "status": "<resolved|firing>", "receiver": <string>, "groupLabels": <object>, "commonLabels": <object>, "commonAnnotations": <object>, "externalURL": <string>, // backlink to the Alertmanager. "alerts": [ { "labels": <object>, "annotations": <object>, "startsAt": "<rfc3339>", "endsAt": "<rfc3339>" } ] }
|
使用Golang創建webhook服務
首先我們嘗試使用Golang創建用於接收webhook告警通知的服務。首先創建model包,用於映射ALertmanager發送的告警信息,Alertmanager的一個通知中根據配置的group_by規則可能會包含多條告警信息Alert。創建告警通知對應的結構體Notification。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
package model
import "time"
type Alert struct { Labels map[string]string `json:"labels"` Annotations map[string]string `json:annotations` StartsAt time.Time `json:"startsAt"` EndsAt time.Time `json:"endsAt"` }
type Notification struct { Version string `json:"version"` GroupKey string `json:"groupKey"` Status string `json:"status"` Receiver string `json:receiver` GroupLabels map[string]string `json:groupLabels` CommonLabels map[string]string `json:commonLabels` CommonAnnotations map[string]string `json:commonAnnotations` ExternalURL string `json:externalURL` Alerts []Alert `json:alerts` }
|
這里使用gin-gonic框架創建用於接收Webhook通知的Web服務。定義路由/webhook接收來自Alertmanager的POST請求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
package main
import ( "net/http"
"github.com/gin-gonic/gin" model "github.com/yunlzheng/alertmanaer-dingtalk-webhook/model" )
func main() { router := gin.Default() router.POST("/webhook", func(c *gin.Context) { var notification model.Notification
err := c.BindJSON(¬ification)
if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return }
c.JSON(http.StatusOK, gin.H{"message": " successful receive alert notification message!"})
}) router.Run() }
|
與釘釘集成
釘釘,阿里巴巴出品,專為中國企業打造的免費智能移動辦公平台,提供了即時通訊以及移動辦公等豐富的功能。
釘釘群機器人是釘釘群的高級擴展功能。群機器人可以將第三方服務的信息聚合到群聊中,實現自動化的信息同步。例如:通過聚合GitHub,GitLab等源碼管理服務,實現源碼更新同步;通過聚合Trello,JIRA等項目協調服務,實現項目信息同步。不僅如此,群機器人支持Webhook協議的自定義接入,支持更多可能性。這里我們將演示如果將Alertmanager運維報警提醒通過自定義機器人聚合到釘釘群。
這里將繼續擴展webhook服務,以支持將Alertmanager的告警通知轉發到釘釘平台。完整的示例代碼可以從github倉庫https://github.com/yunlzheng/alertmanaer-dingtalk-webhook中獲取。
自定義webhook群機器人
通過釘釘客戶端(如:桌面或者手機)進入到群設置后選擇“群機器人”。將顯示如下界面:

選擇“自定義機器人”,並且按照提示填寫機器人名稱,獲取機器人webhook地址,如下所示:

webhook機器人創建成功后,用戶就可以使用任何方式向該地址發起HTTP POST請求,即可實現向該群主發送消息。目前自定義機器人支持文本(text),連接(link),markdown三種消息類型。
例如,可以向webhook地址以POST形式發送以下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
{ "msgtype": "markdown", "markdown": { "title":"Prometheus告警信息", "text": "#### 監控指標\n" + "> 監控描述信息\n\n" + "> ###### 告警時間 \n" }, "at": { "atMobiles": [ "156xxxx8827", "189xxxx8325" ], "isAtAll": false } }
|
可以使用curl驗證釘釘webhook是否能夠成功調用:
1 2
|
$ curl -l -H "Content-type: application/json" -X POST -d '{"msgtype": "markdown","markdown": {"title":"Prometheus告警信息","text": "#### 監控指標\n> 監控描述信息\n\n> ###### 告警時間 \n"},"at": {"isAtAll": false}}' https: |
調用成功后,可以在釘釘應用群消息中接收到類似於如下通知消息:

定義轉換器將告警通知轉化為Dingtalk消息對象
這里定義結構體DingTalkMarkdown用於映射Dingtalk的消息體。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
package model
type At struct { AtMobiles []string `json:"atMobiles"` IsAtAll bool `json:"isAtAll"` }
type DingTalkMarkdown struct { MsgType string `json:"msgtype"` At *At `json:at` Markdown *Markdown `json:"markdown"` }
type Markdown struct { Title string `json:"title"` Text string `json:"text"` }
|
定義轉換器將Alertmanager發送的告警通知轉換為Dingtalk的消息體。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
package transformer
import ( "bytes" "fmt"
"github.com/yunlzheng/alertmanaer-dingtalk-webhook/model" )
|
創建Dingtalk通知發送包
notifier包中使用golang的net/http包實現與Dingtalk群機器人的交互。Send方法包含兩個參數:接收到的告警通知結構體指針,以及Dingtalk群機器人的Webhook地址。
通過包transformer.TransformToMarkdown將Alertmanager告警通知與Dingtalk消息進行映射。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
package notifier
import ( "bytes" "encoding/json" "fmt" "net/http"
"github.com/yunlzheng/alertmanaer-dingtalk-webhook/model" "github.com/yunlzheng/alertmanaer-dingtalk-webhook/transformer" )
func Send(notification model.Notification, dingtalkRobot string) (err error) {
markdown, err := transformer.TransformToMarkdown(notification)
if err != nil { return }
data, err := json.Marshal(markdown) if err != nil { return }
req, err := http.NewRequest( "POST", dingtalkRobot, bytes.NewBuffer(data))
if err != nil { return }
req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req)
if err != nil { return }
defer resp.Body.Close() fmt.Println("response Status:", resp.Status) fmt.Println("response Headers:", resp.Header)
return }
|
擴展啟動函數
首先為程序添加命令行參數支持,用於在啟動時添加全局的Dingtalk群聊機器人地址。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
package main
import ( "flag" ... "github.com/yunlzheng/alertmanaer-dingtalk-webhook/notifier" )
var ( h bool defaultRobot string )
func init() { flag.BoolVar(&h, "h", false, "help") flag.StringVar(&defaultRobot, "defaultRobot", "", "global dingtalk robot webhook") }
func main() {
flag.Parse()
if h { flag.Usage() return }
...
}
|
同時通過notifier包的Send方法將告警通知發送給Dingtalk群聊機器人
1 2 3 4 5 6 7 8 9 10 11 12 13
|
func main() {
...
err = notifier.Send(notification, defaultRobot)
if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
}
c.JSON(http.StatusOK, gin.H{"message": "send to dingtalk successful!"}) }
|
使用Dingtalk擴展
運行並啟動dingtalk webhook服務之后,修改Alertmanager配置文件, 為default-receiver添加webhook配置,如下所示:
1 2 3 4 5 6
|
receivers: - name: default-receiver email_configs: - to: yunl.zheng@wise2c.com webhook_configs: - url: http: |
重啟Alertmanager服務后,手動拉高虛擬機CPU使用率觸發告警條件,此時Dingtalk即可接收到相應的告警通知信息: