/
send.go
199 lines (188 loc) · 6.43 KB
/
send.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package initial
import (
"encoding/json"
"github.com/Qihoo360/doraemon/cmd/alert-gateway/common"
"github.com/Qihoo360/doraemon/cmd/alert-gateway/logs"
"github.com/Qihoo360/doraemon/pkg/notify"
"github.com/astaxie/beego"
"runtime"
"strconv"
"strings"
"time"
)
/*
send alert if rule is triggered.
*/
func Sender(SendClass map[string][]common.Ready2Send, now string) {
for k, v := range SendClass {
switch k {
case common.AlertMethodSms:
go SendAll(k, "mis", map[string]string{"key": "6E358A78-0A5B-49D2-A12F-6A4EB07A9671"}, v, now)
case common.AlertMethodLanxin:
go SendAll(k, "StreeAlert", map[string]string{"key": "6E358A78-0A5B-49D2-A12F-6A4EB07A9671"}, v, now)
//logs.Alertloger.Info("[%s]%v:", now, v)
case common.AlertMethodCall:
go SendAll(k, "StreeAlert", map[string]string{"key": "6E358A78-0A5B-49D2-A12F-6A4EB07A9671"}, v, now)
default:
route3rdChannel(strings.Split(k, " "), v, now)
}
}
}
func route3rdChannel(method []string, content []common.Ready2Send, sendTime string) {
switch method[0] {
case common.AlertMethodHook:
go Send2Hook(content, sendTime, "alert", method[1])
case common.AlertMethodDingTalk:
go notify.Send2DingTalk(content, false, sendTime, method[1], method[2])
}
}
/*
send recovery message if alert recovered.
*/
func RecoverSender(SendClass map[string]map[[2]int64]*common.Ready2Send, now string) {
lanxin := []common.Ready2Send{}
for _, v := range SendClass[common.AlertMethodLanxin] {
lanxin = append(lanxin, *v)
}
go SendRecover(beego.AppConfig.String("LanxinUrl"), "StreeAlert", map[string]string{"key": "6E358A78-0A5B-49D2-A12F-6A4EB07A9671"}, lanxin, now)
//logs.Panic.Info("send[%s]:%v", now, lanxin)
delete(SendClass, common.AlertMethodLanxin)
for k := range SendClass {
var hook []common.Ready2Send
for _, u := range SendClass[k] {
hook = append(hook, *u)
}
// split by space
t := strings.Split(k, " ")
// route to special channel
switch t[0] {
case common.AlertMethodHook:
go Send2Hook(hook, now, "recover", t[1])
case common.AlertMethodDingTalk:
go notify.Send2DingTalk(hook, true, now, t[1], t[2])
default:
go Send2Hook(hook, now, "recover", k[5:])
}
}
}
func SendAll(method string, from string, param map[string]string, content []common.Ready2Send, sendTime string) {
defer func() {
if e := recover(); e != nil {
buf := make([]byte, 16384)
buf = buf[:runtime.Stack(buf, false)]
logs.Panic.Error("Panic in SendAll:%v\n%s", e, buf)
}
}()
if method == common.AlertMethodSms {
url := beego.AppConfig.String("SmsUrl")
for _, i := range content {
msg := []string{"[故障:" + strconv.FormatInt(int64(len(i.Alerts)), 10) + "条] " + i.Alerts[0].Summary}
msg = append(msg, "[时间] "+sendTime)
data, _ := json.Marshal(common.Msg{
Content: strings.Join(msg, "\n"),
From: from,
Title: "Alerts",
To: i.User,
})
common.HttpPost(url, param, nil, data)
}
} else if method == common.AlertMethodLanxin {
url := beego.AppConfig.String("LanxinUrl")
for _, i := range content {
msg := []string{"[故障:" + strconv.FormatInt(int64(len(i.Alerts)), 10) + "条] " + i.Alerts[0].Summary}
for _, j := range i.Alerts {
duration, _ := time.ParseDuration(strconv.FormatInt(int64(j.Count), 10) + "m")
id := strconv.FormatInt(j.Id, 10)
value := strconv.FormatFloat(j.Value, 'f', 2, 64)
msg = append(msg, "["+duration.String()+"][ID:"+id+"] "+j.Hostname+" 当前值:"+value)
}
msg = append(msg, "[时间] "+sendTime)
msg = append(msg, "[确认链接] "+beego.AppConfig.String("WebUrl")+"/alerts_confirm/"+strconv.FormatInt(i.RuleId, 10)+"?start="+strconv.FormatInt(i.Start, 10))
data, _ := json.Marshal(common.Msg{
Content: strings.Join(msg, "\n"),
From: from,
Title: "Alerts",
To: i.User,
})
common.HttpPost(url, param, nil, data)
}
} else {
url := beego.AppConfig.String("CallUrl")
for _, i := range content {
msg := []string{"故障" + strconv.FormatInt(int64(len(i.Alerts)), 10) + "条 " + i.Alerts[0].Summary + " 详细信息请到蓝信查看"}
data, _ := json.Marshal(common.Msg{
Content: strings.Join(msg, "\n"),
From: from,
Title: "Alerts",
To: i.User,
})
common.HttpPost(url, param, nil, data)
}
}
}
type hookRequest struct {
Type string `json:"type"`
Time string `json:"time"`
RuleId int64 `json:"rule_id"`
To []string `json:"to"`
Alerts []common.SingleAlert `json:"alerts"`
ConfirmLink string `json:"confirm_link,omitempty"`
}
func Send2Hook(content []common.Ready2Send, sendTime string, t string, url string) {
defer func() {
if e := recover(); e != nil {
buf := make([]byte, 16384)
buf = buf[:runtime.Stack(buf, false)]
logs.Panic.Error("Panic in Send2Hook:%v\n%s", e, buf)
}
}()
if t == "recover" {
for _, i := range content {
data, _ := json.Marshal(hookRequest{
Type: t,
RuleId: i.RuleId,
Time: sendTime,
To: i.User,
Alerts: i.Alerts,
})
common.HttpPost(url, nil, common.GenerateJsonHeader(), data)
}
} else {
for _, i := range content {
data, _ := json.Marshal(hookRequest{
Type: t,
RuleId: i.RuleId,
Time: sendTime,
ConfirmLink: beego.AppConfig.String("WebUrl") + "/alerts_confirm/" + strconv.FormatInt(i.RuleId, 10) + "?start=" + strconv.FormatInt(i.Start, 10),
To: i.User,
Alerts: i.Alerts,
})
common.HttpPost(url, nil, common.GenerateJsonHeader(), data)
}
}
}
func SendRecover(url string, from string, param map[string]string, content []common.Ready2Send, sendTime string) {
defer func() {
if e := recover(); e != nil {
buf := make([]byte, 16384)
buf = buf[:runtime.Stack(buf, false)]
logs.Panic.Error("Panic in SendRecover:%v\n%s", e, buf)
}
}()
for _, i := range content {
msg := []string{"[故障恢复:" + strconv.FormatInt(int64(len(i.Alerts)), 10) + "条] " + i.Alerts[0].Summary}
for _, j := range i.Alerts {
duration, _ := time.ParseDuration(strconv.FormatInt(int64(j.Count), 10) + "m")
id := strconv.FormatInt(j.Id, 10)
value := strconv.FormatFloat(j.Value, 'f', 2, 64)
msg = append(msg, "["+duration.String()+"][ID:"+id+"] "+j.Hostname+" 当前值:"+value)
}
msg = append(msg, "[时间] "+sendTime)
data, _ := json.Marshal(common.Msg{
Content: strings.Join(msg, "\n"),
From: from,
Title: "Alerts",
To: i.User})
common.HttpPost(url, param, nil, data)
}
}