钉钉报警插件已打包在镜像,不想麻烦的可以直接pull

其他两个平台实时同步

加密token

1
echo -n 'token' | base64

alertGo-deployment.yaml

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
apiVersion: v1
kind: Secret
metadata:
name: dd-token
namespace: ops
type: Opaque
data:
token: '加密后的token'
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: alertgo
namespace: ops
spec:
selector:
matchLabels:
app: alertgo
replicas: 1
template:
metadata:
labels:
app: alertgo
spec:
containers:
- name: alertgo
image: alexcld/alertgo:v3
env:
- name: token
valueFrom:
secretKeyRef:
name: dd-token
key: token
ports:
- containerPort: 8088
livenessProbe:
httpGet:
path: /
port: 8088
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 1
readinessProbe:
httpGet:
path: /
port: 8088
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
timeoutSeconds: 1
lifecycle:
preStop:
exec:
command: ["/bin/bash","-c","sleep 20"]
---
apiVersion: v1
kind: Service
metadata:
name: alertgo
namespace: ops
spec:
selector:
app: alertgo
ports:
- port: 80
targetPort: 8088

kubectl apply -f alertGo-deployment.yaml

修改alertmanager-configmap.yaml

在这里插入图片描述

1
2
3
webhook_configs:
- url: 'http://clusterIP/Alert'
send_resolved: true

至此完成

go环境部署及打包钉钉报警插件

其他两个平台实时同步

下载解压

1
2
3
cd /opt && wget https://golang.org/dl/go1.13.10.linux-amd64.tar.gz
#解压至/usr/local
tar -zxvf go1.13.10.linux-amd64.tar.gz

创建/opt/gocode/{src,bin,pkg},用于设置GOPATH为/opt/gocode

1
2
3
4
5
6
mkdir -p /opt/gocode/{src,bin,pkg}

/opt/gocode/
├── bin
├── pkg
└── src

修改/etc/profile系统环境变量文件,写入GOPATH信息以及go sdk路径

1
2
3
4
5
6
export GOROOT=/opt/go           #Golang源代码目录,安装目录
export GOPATH=/opt/gocode #Golang项目代码目录
export PATH=$GOROOT/bin:$PATH #Linux环境变量
export GOBIN=$GOPATH/bin #go install后生成的可执行命令存放路径
# 保存退出后source一下
source /etc/profile

执行go version

1
2
[root@localhost gocode]# go version
go version go1.13.10 linux/amd64

运行程序并打包

安装gin web框架

爬过梯子的可以直接安装,不再赘述如何爬梯子,如果没有爬梯子的话 需要设置下GOPROXY

1
2
3
4
5
6
7
8
9
golang 1.13 可以直接执行:

七牛云
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct

阿里云
go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

安装gin依赖

1
go get -u github.com/gin-gonic/gin

创建go文件

1
2
mkdir -p $GOPATH/alertgo && cd $GOPATH/alertgo
touch alertGo.go
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package main

import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"time"

"github.com/gin-gonic/gin"
)

//const (
// webHook_Alert = "https://oapi.dingtalk.com/robot/send?access_token=724402cd85e7e80aa5bbbb7d7a89c74db6a3a8bd8fac4c91923ed3f906664ba4"
//)
type Message struct {
MsgType string `json:"msgtype"`
Text struct {
Content string `json:"content"`
Mentioned_list string `json:"mentioned_list"`
Mentioned_mobile_list string `json:"mentioned_mobile_list"`
} `json:"text"`
}
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`
}

//获取报警信息
func getAlertInfo(notification Notification) string {
var m Message
m.MsgType = "text"
//告警消息
//重新定义报警消息
var newbuffer bytes.Buffer
//定义恢复消息
var recoverbuffer bytes.Buffer
fmt.Println(notification)
fmt.Println(notification.Status)
if notification.Status == "resolved" {
for _, alert := range notification.Alerts {
recoverbuffer.WriteString(fmt.Sprintf("状态已经恢复!!!!\n"))
recoverbuffer.WriteString(fmt.Sprintf(" **项目: 恢复时间:**%s\n\n", alert.StartsAt.Add(8*time.Hour).Format("2006-01-02 15:04:05")))
recoverbuffer.WriteString(fmt.Sprintf("项目: 告警主题: %s \n", alert.Annotations["summary"]))

}

} else {
for _, alert := range notification.Alerts {
newbuffer.WriteString(fmt.Sprintf("==============Start============ \n"))
newbuffer.WriteString(fmt.Sprintf("项目: 告警程序:prometheus_alert_email \n"))
newbuffer.WriteString(fmt.Sprintf("项目: 告警级别: %s \n", alert.Labels["severity"]))
newbuffer.WriteString(fmt.Sprintf("项目: 告警类型: %s \n", alert.Labels["alertname"]))
newbuffer.WriteString(fmt.Sprintf("项目: 故障主机: %s \n", alert.Labels["instance"]))
newbuffer.WriteString(fmt.Sprintf("项目: 告警主题: %s \n", alert.Annotations["summary"]))
newbuffer.WriteString(fmt.Sprintf("项目: 告警详情: %s \n", alert.Annotations["description"]))
newbuffer.WriteString(fmt.Sprintf(" **项目: 开始时间:**%s\n\n", alert.StartsAt.Add(8*time.Hour).Format("2006-01-02 15:04:05")))
newbuffer.WriteString(fmt.Sprintf("==============End============ \n"))
}
}

if notification.Status == "resolved" {
m.Text.Content = recoverbuffer.String()
} else {
m.Text.Content = newbuffer.String()
}
jsons, err := json.Marshal(m)
if err != nil {
fmt.Println("解析发送钉钉的信息有问题!!!!")
}
resp := string(jsons)
return resp
}

//钉钉报警
func SendAlertDingMsg(msg string) {
defer func() {
if err := recover(); err != nil {
fmt.Println("err")
}
}()
token := os.Getenv("token")
webHook_Alert := "https://oapi.dingtalk.com/robot/send?access_token=" + token
fmt.Println("开始发送报警消息!!!")
fmt.Println(webHook_Alert)
//content := `{"msgtype": "text",
// "text": {"content": "` + msg + `"}
//}`

//创建一个请求
req, err := http.NewRequest("POST", webHook_Alert, strings.NewReader(msg))
if err != nil {
fmt.Println(err)
fmt.Println("钉钉报警请求异常")
}
client := &http.Client{}
//设置请求头
req.Header.Set("Content-Type", "application/json; charset=utf-8")
//发送请求
resp, err := client.Do(req)
if err != nil {
// handle error
fmt.Println(err)
fmt.Println("顶顶报发送异常!!!")
}
defer resp.Body.Close()
}
func AlertInfo(c *gin.Context) {
var notification Notification
fmt.Println("接收到的信息是....")
fmt.Println(notification)
err := c.BindJSON(&notification)
fmt.Printf("%#v", notification)
if err != nil {
fmt.Println("绑定信息错误!!!")
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
} else {
fmt.Println("绑定信息成功")
}
fmt.Println("绑定信息成功!!!")
msg := getAlertInfo(notification)
fmt.Println("打印的信息是.....")
fmt.Println(msg)
SendAlertDingMsg(msg)

}
func main() {
t := gin.Default()
t.POST("/Alert", AlertInfo)
t.GET("/", func(c *gin.Context) {
c.String(http.StatusOK, `<h1>关于alertmanager实现钉钉报警的方法V6!!!</h1>`+"\n新增了报警恢复机制!!!")
})
t.Run(":8088")
}

最后将go文件打包为linux二进制可运行程序

1
go build alertGo.go

运行alertGo程序

1
2
3
4
5
6
7
8
###赋权
chmod 775 alertGo
###后台运行
nohup /root/prometheus/alertGo/alertGo > alertGo.log 2>&1 &
###查看端口进程
lsof -i:8088
###查看日志
tail -f alertGo.log

修改alertmanager-configmap.yaml

在这里插入图片描述

1
2
3
webhook_configs:
- url: 'http://xxxxx:8088/Alert'
send_resolved: true

热更新prometheus

1
2
3
kubectl apply -f alertmanager-configmap.yaml
###alertmanager clusterIP
curl -X POST http://10.1.229.17/-/reload

然后触发报警,钉钉就可以正常收取了,
在这里插入图片描述

在此感谢大佬的代码