From 0257fc7d85bd5f3441303a8dd4deb8b81494704f Mon Sep 17 00:00:00 2001 From: maybachv5 <289727461@qq.com> Date: Sat, 30 May 2020 10:06:41 +0800 Subject: [PATCH] add dingtalk alarm --- configs/alarm.yml | 4 ++ modules/alarm/g/config.go | 29 ++++++++------ modules/alarm/g/var.go | 15 +++++++- modules/alarm/sender/builder.go | 29 ++++++++++++++ modules/alarm/sender/sender.go | 67 ++++++++++++++++++++++++++++++--- 5 files changed, 127 insertions(+), 17 deletions(-) diff --git a/configs/alarm.yml b/configs/alarm.yml index dd843fa..c492c30 100644 --- a/configs/alarm.yml +++ b/configs/alarm.yml @@ -19,8 +19,12 @@ wechat: agentid: 1000008 corpid: "" corpsecret: "" +dingtalk: + enabled: true + accesstoken: "xxxx" worker: sms: 10 #send sms concurrency mail: 50 #send mail concurrency wechat: 50 #send wechat concurrency + dingtalk: 50 #send dingtalk concurrency # remain: 30 diff --git a/modules/alarm/g/config.go b/modules/alarm/g/config.go index da26338..2043d9d 100644 --- a/modules/alarm/g/config.go +++ b/modules/alarm/g/config.go @@ -10,14 +10,15 @@ import ( ) type GlobalConfig struct { - Debug bool `yaml:"debug"` - SmsEnabled bool `yaml:"smsEnabled"` - Remain int `yaml:"remain"` - Rpc *RpcConfig `yaml:"rpc"` - Web *WebConfig `yaml:"web"` - Worker *WorkerConfig `yaml:"worker"` - Smtp *SmtpConfig `yaml:"smtp"` - WeChat *WeChatConfig `yaml:"wechat"` + Debug bool `yaml:"debug"` + SmsEnabled bool `yaml:"smsEnabled"` + Remain int `yaml:"remain"` + Rpc *RpcConfig `yaml:"rpc"` + Web *WebConfig `yaml:"web"` + Worker *WorkerConfig `yaml:"worker"` + Smtp *SmtpConfig `yaml:"smtp"` + WeChat *WeChatConfig `yaml:"wechat"` + DingTalk *DingTalkConfig `yaml:"dingtalk"` } type MysqlConfig struct { @@ -37,9 +38,10 @@ type WebConfig struct { } type WorkerConfig struct { - Sms int `yaml:"sms"` - Mail int `yaml:"mail"` - WeChat int `yaml:"wechat"` + Sms int `yaml:"sms"` + Mail int `yaml:"mail"` + WeChat int `yaml:"wechat"` + DingTalk int `yaml:"dingtalk"` } type SmtpConfig struct { @@ -59,6 +61,11 @@ type WeChatConfig struct { CorpSecret string `yaml:corpsecret` } +type DingTalkConfig struct { + Enabled bool `yaml:"enabled"` + AccessToken string `yaml:"accesstoken"` +} + var ( Config *GlobalConfig configLock = new(sync.RWMutex) diff --git a/modules/alarm/g/var.go b/modules/alarm/g/var.go index b485ef7..cf588f0 100644 --- a/modules/alarm/g/var.go +++ b/modules/alarm/g/var.go @@ -23,6 +23,11 @@ type WeChat struct { Content string `json:"content"` } +type DingTalk struct { + Tos string `json:"tos"` + Content string `json:"content"` +} + func (this *Sms) String() string { return fmt.Sprintf( "", @@ -46,4 +51,12 @@ func (this *WeChat) String() string { this.Tos, this.Content, ) -} \ No newline at end of file +} + +func (this *DingTalk) String() string { + return fmt.Sprintf( + "", + this.Tos, + this.Content, + ) +} diff --git a/modules/alarm/sender/builder.go b/modules/alarm/sender/builder.go index f6c746d..cad24b1 100644 --- a/modules/alarm/sender/builder.go +++ b/modules/alarm/sender/builder.go @@ -57,6 +57,23 @@ func BuildWeChat(event *dataobj.Event) string { ) } +func BuildDingTalk(event *dataobj.Event) string { + strategy, _ := cache.StrategyMap.Get(event.StrategyId) + respTime := fmt.Sprintf("%dms", event.RespTime) + return fmt.Sprintf( + "### 站点监控\n>- 站点状态: **%s**\n>- 站点地址: **<%s>**\n>- 备注信息: **%s**\n>- 监控主机: **%s**\n>- 返回状态码: **%s**\n>- 响应时间: **%s**\n>- 告警时间: **%s**\n>- 告警次数: **%d**\n", + //"状态:%s\nUrl:%s\n备注:%s\nIP:%s\n返回状态码:%s\n响应时间:%s\n时间:%s\n报警次数:%d\n", + event.Status, + event.Url, + strategy.Note, + event.Ip, + event.RespCode, + respTime, + humanTime(event.EventTime), + event.CurrentStep, + ) +} + func humanTime(ts int64) string { return time.Unix(ts, 0).Format("2006-01-02 15:04:05") } @@ -113,3 +130,15 @@ func WriteWeChat(tos []string, content string) { WeChatWorkerChan <- 1 go sendWeChat(weChat) } + +func WriteDingTalk(tos []string, content string) { + if !g.Config.DingTalk.Enabled { + return + } + if len(tos) == 0 { + return + } + DingTalk := &g.DingTalk{Tos: strings.Join(tos, ","), Content: content} + DingTalkWorkerChan <- 1 + go sendDingTalk(DingTalk) +} diff --git a/modules/alarm/sender/sender.go b/modules/alarm/sender/sender.go index 8dfbcce..3e95536 100644 --- a/modules/alarm/sender/sender.go +++ b/modules/alarm/sender/sender.go @@ -25,10 +25,11 @@ import ( ) var ( - SmsWorkerChan chan int - MailWorkerChan chan int - WeChatWorkerChan chan int - requestError = errors.New("request error,check url or network") + SmsWorkerChan chan int + MailWorkerChan chan int + WeChatWorkerChan chan int + DingTalkWorkerChan chan int + requestError = errors.New("request error,check url or network") ) const ( @@ -36,6 +37,8 @@ const ( sendUrl = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" // 获取token使用导的url getToken = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + // 钉钉webhook + webHook = "https://oapi.dingtalk.com/robot/send?access_token=" ) func Init() { @@ -43,26 +46,31 @@ func Init() { SmsWorkerChan = make(chan int, workerConfig.Sms) MailWorkerChan = make(chan int, workerConfig.Mail) WeChatWorkerChan = make(chan int, workerConfig.WeChat) + DingTalkWorkerChan = make(chan int, workerConfig.DingTalk) } func SendEvent(event *dataobj.Event) { mail := make([]string, 0) sms := make([]string, 0) weChat := make([]string, 0) + dingTalk := make([]string, 0) users := getUsers(event.StrategyId) mailContent := BuildMail(event) smsContent := BuildSms(event) weChatContent := BuildWeChat(event) + dingTalkContent := BuildDingTalk(event) for _, user := range users { mail = append(mail, user.Email) sms = append(sms, user.Phone) weChat = append(weChat, user.Wechat) + dingTalk = append(dingTalk, user.Phone) } WriteSms(sms, smsContent) WriteMail(mail, smsContent, mailContent) WriteWeChat(weChat, weChatContent) + WriteDingTalk(dingTalk, dingTalkContent) } func sendSms(phone string, sms string) { @@ -135,6 +143,28 @@ func sendWeChat(weChat *g.WeChat) { } } +func sendDingTalk(dingTalk *g.DingTalk) { + defer func() { + <-DingTalkWorkerChan + }() + var msg = dingTalkMsg{ + MsgType: "markdown", + MarkDown: map[string]string{"title": "站点监控", "text": dingTalk.Content}, + } + buf, err := json.Marshal(msg) + if err != nil { + log.Println(err, "marshal dingTalk msg error") + } + err = SendDingTalk(g.Config.DingTalk.AccessToken, buf) + if err != nil { + log.Println(err, "send dingTalk") + } else { + log.Println("==dingTalk==>>>>", dingTalk) + log.Println("<<<<==dingTalk==", string(buf)) + } + +} + func getUsers(sid int64) []*dataobj.User { var usersResp api.UsersResponse var users []*dataobj.User @@ -169,7 +199,13 @@ type weChatMsg struct { Safe int `json:"safe"` } -// 定义微信错误返回结构体 +// 定义钉钉markdown消息结构体 +type dingTalkMsg struct { + MsgType string `json:"msgtype"` + MarkDown map[string]string `json:"markdown"` +} + +// 定义微信/钉钉错误返回结构体 type sendMsgError struct { ErrCode int `json:"errcode` ErrMsg string `json:"errmsg"` @@ -219,3 +255,24 @@ func SendMsg(AccessToken string, msgBody []byte) error { } return nil } + +// 发送钉钉 +func SendDingTalk(AccessToken string, msgBody []byte) error { + body := bytes.NewBuffer(msgBody) + resp, err := http.Post(webHook+AccessToken, "application/json", body) + if resp.StatusCode != 200 { + return requestError + } + buf, _ := ioutil.ReadAll(resp.Body) + resp.Body.Close() + var e sendMsgError + err = json.Unmarshal(buf, &e) + if err != nil { + return err + } + if e.ErrCode != 0 && e.ErrMsg != "ok" { + return errors.New(string(buf)) + } + return nil + +}