golang接收alertmanager的告警併傳送釘釘

尹正杰發表於2024-11-14

                                              作者:尹正傑

版權宣告:原創作品,謝絕轉載!否則將追究法律責任。

目錄
  • 一.配置釘釘
    • 1.釘釘自定義機器人接入參考文件
    • 2.配置釘釘機器人
  • 二.alertmanager實現告警併傳送釘釘
    • 1.編寫原始碼接收告警處理
    • 2.修改alertmanager配置檔案
    • 3.配置Prometheus的規則檔案
    • 4.重啟服務,觀察配置是否觸發告警
    • 5.驗證釘釘配置是否生效

一.配置釘釘

1.釘釘自定義機器人接入參考文件

參考連結:
	https://open.dingtalk.com/document/orgapp/custom-robot-access

2.配置釘釘機器人

如上圖所示,註冊釘釘拉群聊,然後新增“自定義機器人”,並配置自定義關鍵詞,該關鍵字的作用就是當訊息傳送到釘釘群前,會檢查該訊息是否包含關鍵字,若包含則會在群裡顯示,若不包含關鍵字則不會傳送訊息到群裡,這意味著群成員無法檢視。


這相當於一個"口令",一定要確保你的訊息確保有該關鍵詞。

二.alertmanager實現告警併傳送釘釘

1.編寫原始碼接收告警處理

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/prometheus/alertmanager/notify/webhook"
	"github.com/prometheus/alertmanager/template"
)

// DingMessage 定義訊息結構體,最終欄位結構需要符合官方的定義,參考連結:
//
//	https://open.dingtalk.com/document/orgapp/custom-robot-access#title-72m-8ag-pqw
type DingMessage struct {
	Msgtype string `json:"msgtype"`

	Text struct {
		Content string `json:"content"`
	} `json:"text"`

	At struct {
		AtMobiles []string `json:"atMobiles"`
	} `json:"at"`
}

// buildDingDingContent 拼接釘釘訊息的函式
func buildDingDingContent(msg template.Alert) ([]byte, error) {

	recM := map[string]string{"firing": "已觸發", "resolved": "已恢復"}

	msgTpl := fmt.Sprintf(
		"規則名稱: %s\n"+
			"是否已經恢復: %s\n"+
			"告警級別: %s\n"+
			"觸發時間: %s\n"+
			"看圖連線: %s\n"+
			"當前值: %s\n"+
			"標籤組: %s",
		msg.Labels["alertname"],
		recM[msg.Status],
		msg.Labels["severity"],
		msg.StartsAt.In(time.Local).Format("2006-01-02 15:04:05"),
		msg.GeneratorURL,
		msg.Annotations["value"],
		msg.Labels.SortedPairs(),
	)

	dm := DingMessage{Msgtype: "text"}

	dm.Text.Content = msgTpl

	bs, err := json.Marshal(dm)

	return bs, err

}

// SendToDing 傳送訊息到釘釘
func SendToDing(jsonByte []byte) {

	// 注意哈,這個口令換成你的釘釘群機器人的webhook即可。
	dingDingUrl := "https://oapi.dingtalk.com/robot/send?access_token=7cd79af7b9a29f1877438f53f4be10e6f744bb0dae39bb256eee518bebe46cd5"

	req, err := http.NewRequest("POST", dingDingUrl, bytes.NewBuffer(jsonByte))
	if err != nil {
		log.Printf("err = %v\n", err)
		return
	}

	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}

	resp, err := client.Do(req)

	log.Printf("釘釘傳送完成")
	if err != nil {
		log.Printf("http.post.request.err|url:%v|err:%v", dingDingUrl, err)
		return
	}

	defer resp.Body.Close()
}

func AlertReceiveFunc(c *gin.Context) {
	var msg webhook.Message

	if err := c.BindJSON(&msg); err != nil {
		c.JSON(400, errors.New("invalid args"))
		return
	}

	baseMsg := fmt.Sprintf("狀態: %s|報警條數: %d", msg.Status, len(msg.Alerts))

	log.Printf("alertReceive|baseMsg:%+v", baseMsg)

	for i := 0; i < len(msg.Alerts); i++ {
		alert := msg.Alerts[i]

		bs, _ := buildDingDingContent(alert)
		log.Printf("detail|%d/%d|alert:%+v", i+1, len(msg.Alerts), alert)

		SendToDing(bs)
	}

	c.JSON(http.StatusOK, "ok")
}

func main() {

	listenAddr := flag.String("addr", ":8888", "WebUI expose port")
	flag.Parse()

	r := gin.Default()

	r.POST("/alert", AlertReceiveFunc)
	r.Run(*listenAddr)
}

2.修改alertmanager配置檔案

[root@prometheus-server31 ~]# cat /yinzhengjie/softwares/alertmanager-0.27.0.linux-amd64/alertmanager.yml 
route:
  group_by: ['alertname']
  group_wait: 1s
  group_interval: 3s
  repeat_interval: 10s
  receiver: 'web.hook'
receivers:
  - name: 'web.hook'
    webhook_configs:
      - url: 'http://10.0.0.1:8888/alert'
        http_config: {}
        max_alerts: 0
        send_resolved: true
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']
[root@prometheus-server31 ~]# 

3.配置Prometheus的規則檔案

[root@prometheus-server31 ~]# cat /yinzhengjie/softwares/prometheus-2.53.2.linux-amd64/yinzhengjie_rules.yml 
groups:
- name: xixi
  rules:
    - alert: yinzhengjie_mysqld_exporter-alert
      expr: node_boot_time_seconds{instance="10.0.0.42:9100", job="yinzhengjie_mysqld_exporter"} > 0
      labels:
        severity: critical
        blog: "https://www.cnblogs.com/yinzhengjie"
      annotations:
        summary: DBA機器異常

- name: haha
  rules:
    - alert: yinzhengjie_bigdata_exporter-alert
      expr: node_boot_time_seconds{instance="10.0.0.41:9100", job="yinzhengjie_bigdata_exporter"} > 0
      labels:
        severity: warning
        auther: 尹正傑
      annotations:
        summary: 大資料叢集機器異常
[root@prometheus-server31 ~]# 

4.重啟服務,觀察配置是否觸發告警

	1.修改Prometheus的啟動指令碼並新增如下的啟動引數
--web.external-url=http://10.0.0.31:9090/

[root@prometheus-server31 ~]# systemctl daemon-reload 


	2.重啟服務
[root@prometheus-server31 ~]# systemctl restart prometheus-server.service alertmanager.service 


如上圖所示,我的測試程式碼已經成功傳送告警啦。

5.驗證釘釘配置是否生效

如上圖所示,我們的配置告警資訊成功啦。

相關文章