add mm notification

This commit is contained in:
kongfei 2022-08-31 14:11:28 +08:00
parent 8c45479c02
commit 5e931ebe8e
8 changed files with 103 additions and 2 deletions

View File

@ -76,7 +76,7 @@ Batch = 5
TemplatesDir = "./etc/template"
NotifyConcurrency = 10
# use builtin go code notify
NotifyBuiltinChannels = ["email", "dingtalk", "wecom", "feishu"]
NotifyBuiltinChannels = ["email", "dingtalk", "wecom", "feishu", "mm"]
[Alerting.CallScript]
# built in sending capability in go code

7
etc/template/mm.tpl Normal file
View File

@ -0,0 +1,7 @@
级别状态: S{{.Severity}} {{if .IsRecovered}}Recovered{{else}}Triggered{{end}}
规则名称: {{.RuleName}}{{if .RuleNote}}
规则备注: {{.RuleNote}}{{end}}
监控指标: {{.TagsJSON}}
{{if .IsRecovered}}恢复时间:{{timeformat .LastEvalTime}}{{else}}触发时间: {{timeformat .TriggerTime}}
触发时值: {{.TriggerValue}}{{end}}
发送时间: {{timestamp}}

View File

@ -39,6 +39,11 @@ Label = "飞书机器人"
# do not change Key
Key = "feishu"
[[NotifyChannels]]
Label = "mm bot"
# do not change Key
Key = "mm"
[[ContactKeys]]
Label = "Wecom Robot Token"
# do not change Key
@ -54,6 +59,11 @@ Label = "Feishu Robot Token"
# do not change Key
Key = "feishu_robot_token"
[[ContactKeys]]
Label = "MatterMost Webhook URL"
# do not change Key
Key = "mm_webhook_url"
[Log]
# log write dir
Dir = "logs"
@ -207,4 +217,4 @@ Timeout = 3000
TargetUp = '''max(max_over_time(target_up{ident=~"(%s)"}[%dm])) by (ident)'''
LoadPerCore = '''max(max_over_time(system_load_norm_1{ident=~"(%s)"}[%dm])) by (ident)'''
MemUtil = '''100-max(max_over_time(mem_available_percent{ident=~"(%s)"}[%dm])) by (ident)'''
DiskUtil = '''max(max_over_time(disk_used_percent{ident=~"(%s)", path="/"}[%dm])) by (ident)'''
DiskUtil = '''max(max_over_time(disk_used_percent{ident=~"(%s)", path="/"}[%dm])) by (ident)'''

View File

@ -50,6 +50,9 @@ func SendDingtalk(message DingtalkMessage) {
}
ur := "https://oapi.dingtalk.com/robot/send?access_token=" + u.Path
if strings.HasPrefix(u.Path, "https://") {
ur = u.Path
}
body := dingtalk{
Msgtype: "markdown",
Markdown: dingtalkMarkdown{

View File

@ -1,6 +1,7 @@
package sender
import (
"strings"
"time"
"github.com/didi/nightingale/v5/src/pkg/poster"
@ -31,6 +32,9 @@ type feishu struct {
func SendFeishu(message FeishuMessage) {
for i := 0; i < len(message.Tokens); i++ {
url := "https://open.feishu.cn/open-apis/bot/v2/hook/" + message.Tokens[i]
if strings.HasPrefix(message.Tokens[i], "https://") {
url = message.Tokens[i]
}
body := feishu{
Msgtype: "text",
Content: feishuContent{

View File

@ -0,0 +1,58 @@
package sender
import (
"net/url"
"time"
"github.com/didi/nightingale/v5/src/pkg/poster"
"github.com/toolkits/pkg/logger"
)
type MatterMostMessage struct {
Text string
Tokens []string
}
type mm struct {
Channel string `json:"channel"`
Username string `json:"username"`
Text string `json:"text"`
Props string `json:"props"`
}
func SendMM(message MatterMostMessage) {
for i := 0; i < len(message.Tokens); i++ {
u, err := url.Parse(message.Tokens[i])
if err != nil {
logger.Errorf("mm_sender: failed to parse error=%v", err)
}
v, err := url.ParseQuery(u.RawQuery)
if err != nil {
logger.Errorf("mm_sender: failed to parse query error=%v", err)
}
channels := v["channel"] // do not get
username := v.Get("username")
if err != nil {
logger.Errorf("mm_sender: failed to parse error=%v", err)
}
// simple concatenating
ur := u.Scheme + "://" + u.Host + u.Path
for _, channel := range channels {
body := mm{
Channel: channel,
Username: username,
Text: message.Text,
}
res, code, err := poster.PostJSON(ur, time.Second*5, body, 3)
if err != nil {
logger.Errorf("mm_sender: result=fail url=%s code=%d error=%v response=%s", ur, code, err, string(res))
} else {
logger.Infof("mm_sender: result=succ url=%s code=%d response=%s", ur, code, string(res))
}
}
}
}

View File

@ -1,6 +1,7 @@
package sender
import (
"strings"
"time"
"github.com/didi/nightingale/v5/src/pkg/poster"
@ -24,6 +25,9 @@ type wecom struct {
func SendWecom(message WecomMessage) {
for i := 0; i < len(message.Tokens); i++ {
url := "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=" + message.Tokens[i]
if strings.HasPrefix(message.Tokens[i], "https://") {
url = message.Tokens[i]
}
body := wecom{
Msgtype: "markdown",
Markdown: wecomMarkdown{

View File

@ -64,6 +64,7 @@ func notifyMaintainerWithBuiltin(title, msg, triggerTime string, users []*models
wecomset := make(map[string]struct{})
dingtalkset := make(map[string]struct{})
feishuset := make(map[string]struct{})
mmset := make(map[string]struct{})
for _, user := range users {
if user.Email != "" {
@ -94,6 +95,11 @@ func notifyMaintainerWithBuiltin(title, msg, triggerTime string, users []*models
if ret.Exists() {
feishuset[ret.String()] = struct{}{}
}
ret = gjson.GetBytes(bs, "mm_webhook_url")
if ret.Exists() {
mmset[ret.String()] = struct{}{}
}
}
phones := StringSetKeys(phoneset)
@ -137,6 +143,15 @@ func notifyMaintainerWithBuiltin(title, msg, triggerTime string, users []*models
AtMobiles: phones,
Tokens: StringSetKeys(feishuset),
})
case "mm":
if len(mmset) == 0 {
continue
}
content := "**Title: **" + title + "\n**Content: **" + msg + "\n**Time: **" + triggerTime
sender.SendMM(sender.MatterMostMessage{
Text: content,
Tokens: StringSetKeys(mmset),
})
}
}
}