Skip to content

Commit

Permalink
美化前端页面,增加钉钉@ALL开关,增加alertmanager router接口
Browse files Browse the repository at this point in the history
  • Loading branch information
jikun.zhang committed Jan 10, 2020
1 parent 540291c commit f84045d
Show file tree
Hide file tree
Showing 18 changed files with 264 additions and 66 deletions.
36 changes: 34 additions & 2 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ PrometheusAlert是开源的运维告警中心消息转发系统,支持主流的

--------------------------------------

2.2.1版本更新说明:
---------------------
- 1.增加配置项dd_isatall,功能是否开启钉钉 @所有人(0为关闭,1为开启)
- 2.美化前端页面CSS
- 3.新增接口 /prometheus/router,专门用于处理Prometheus AlertManager的route路由定义的消息(即通过路由指定发送目标),readme中有详细使用方法

--------------------------------------

2.2版本更新说明:
---------------------
- 1.增加阿里云短信接口支持
Expand Down Expand Up @@ -128,7 +136,10 @@ PrometheusAlert 暂提供以下几类接口,分别对应各自接入端

- `prometheus接口`

`/prometheus/alert`
```
/prometheus/alert 默认接口
/prometheus/router AlertManager router指定接收端接口
```

- `grafana接口`

Expand Down Expand Up @@ -171,7 +182,9 @@ PrometheusAlert 暂提供以下几类接口,分别对应各自接入端

- `语音短信回调接口`

`/tengxun/status`
```
/tengxun/status 腾讯语音短信回调接口
```

--------------------------------------
**0. 开启钉钉机器人**
Expand Down Expand Up @@ -215,6 +228,25 @@ receivers:
- url: 'http://[prometheusalert_url]:8080/prometheus/alert'
```

针对 `/prometheus/router AlertManager router指定接收端接口`,该接口可在url中直接指定告警的接收端,目前之前三个参数,分别是:wxurl,ddurl,phone(phone用于短信和电话告警)

在 Prometheus Alertmanager 中启用 Webhook,可参考如下模板:

```
global:
resolve_timeout: 5m
route:
group_by: ['instance']
group_wait: 10m
group_interval: 10s
repeat_interval: 10m
receiver: 'web.hook.prometheusalert'
receivers:
- name: 'web.hook.prometheusalert'
webhook_configs:
- url: 'http://[prometheusalert_url]:8080/prometheus/router?wxurl=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxx&ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx&phone=15395105573'
```

Prometheus Server 的告警rules配置,可参考如下模板:

```
Expand Down
2 changes: 2 additions & 0 deletions conf/app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ silent=1
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=1

#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
Expand Down
7 changes: 6 additions & 1 deletion controllers/dingding.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func PostToDingDing(title,text,Ddurl string)(string) {
if open=="0" {
return "钉钉接口未配置未开启状态,请先配置open-dingding为1"
}
Isatall,_:=beego.AppConfig.Int("dd_isatall")
Atall:=true
if Isatall==0 {
Atall=false
}
u := DDMessage{
Msgtype:"markdown",
Markdown: struct {
Expand All @@ -36,7 +41,7 @@ func PostToDingDing(title,text,Ddurl string)(string) {
At: struct {
AtMobiles []string `json:"atMobiles"`
IsAtAll bool `json:"isAtAll"`
}{AtMobiles:[]string{"15395105573"} , IsAtAll:true },
}{AtMobiles:[]string{"15395105573"} , IsAtAll:Atall },
}
b := new(bytes.Buffer)
json.NewEncoder(b).Encode(u)
Expand Down
100 changes: 98 additions & 2 deletions controllers/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package controllers

import (
"encoding/json"
"fmt"
"github.com/astaxie/beego"
"log"
"sort"
Expand Down Expand Up @@ -67,6 +68,7 @@ func (c *PrometheusController) PrometheusAlert() {
log.Println(c.Data["json"])
c.ServeJSON()
}

//func GetCSTtime(date string)(string) {
// T1:=date[0:10]
// T2:=date[11:19]
Expand Down Expand Up @@ -132,11 +134,11 @@ func SendMessageP(message Prometheus)(string) {
phone:=GetUserPhone(1)
returnMessage = returnMessage + "PostTXmessage:" + PostTXmessage(MobileMessage, phone) + "\n"
returnMessage = returnMessage + "PostHWmessage:" + PostHWmessage(MobileMessage, phone) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostHWmessage(MobileMessage, phone) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostALYmessage(MobileMessage, phone) + "\n"
}else {
returnMessage = returnMessage + "PostTXmessage:" + PostTXmessage(MobileMessage, RMessage.Annotations.Mobile) + "\n"
returnMessage = returnMessage + "PostHWmessage:" + PostHWmessage(MobileMessage, RMessage.Annotations.Mobile) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostHWmessage(MobileMessage, RMessage.Annotations.Mobile) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostALYmessage(MobileMessage, RMessage.Annotations.Mobile) + "\n"
}
}
//发送消息到语音
Expand All @@ -163,5 +165,99 @@ func SendMessageP(message Prometheus)(string) {
return returnMessage
}

func (c *PrometheusController) PrometheusRouter() {
//{"receiver":"prometheus-alert-center","status":"firing","alerts":[{"status":"firing","labels":{"alertname":"KubePodCrashLooping","app":"kube-state-metrics","container":"emqx-test","instance":"172.28.58.250:8080","job":"kubernetes-service-endpoints","kubernetes_name":"kube-state-metrics","kubernetes_namespace":"monitor","level":"3","namespace":"test-mars","pod":"emqx-test-0"},"annotations":{"description":"Pod CrashLooping,test-mars/emqx-test-0 的容器 emqx-test 10分钟重启了5次","level":"3","timestamp":"@2019-12-06 03:00:00.516 +0000 UTC"},"startsAt":"2019-12-06T02:57:50.516115711Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"https://xprometheus-dev.i-tetris.com/graph?g0.expr=increase%28kube_pod_container_status_restarts_total%7Bnamespace%21~%22.%2Adev.%2A%22%7D%5B10m%5D%29+%3E+5\u0026g0.tab=1"},{"status":"firing","labels":{"alertname":"PodNotReady","app":"kube-state-metrics","class":"basic","container":"emqx-test","infrastructure":"true","instance":"172.28.58.250:8080","job":"kubernetes-service-endpoints","kubernetes_name":"kube-state-metrics","kubernetes_namespace":"monitor","level":"2","namespace":"test-mars","pod":"emqx-test-0"},"annotations":{"description":"test-mars/emqx-test-0 was not ready more than 120s.","level":"2","timestamp":"@2019-12-06 02:59:57.829 +0000 UTC"},"startsAt":"2019-12-06T02:12:17.830216179Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"https://xprometheus-dev.i-tetris.com/graph?g0.expr=kube_pod_container_status_ready+%21%3D+1\u0026g0.tab=1"},{"status":"firing","labels":{"alertname":"PodNotReady","app":"kube-state-metrics","class":"basic","container":"emqx-test","infrastructure":"true","instance":"172.28.58.250:8080","job":"kubernetes-service-endpoints","kubernetes_name":"kube-state-metrics","kubernetes_namespace":"monitor","level":"3","namespace":"test-mars","pod":"emqx-test-0"},"annotations":{"description":"test-mars/emqx-test-0 was not ready more than 300s.","level":"3","timestamp":"@2019-12-06 02:59:42.829 +0000 UTC"},"startsAt":"2019-12-06T02:15:17.830216179Z","endsAt":"0001-01-01T00:00:00Z","generatorURL":"https://xprometheus-dev.i-tetris.com/graph?g0.expr=kube_pod_container_status_ready%7Bnamespace%21~%22.%2Adev.%2A%22%7D+%21%3D+1\u0026g0.tab=1"}],"groupLabels":{"instance":"172.28.58.250:8080"},"commonLabels":{"app":"kube-state-metrics","container":"emqx-test","instance":"172.28.58.250:8080","job":"kubernetes-service-endpoints","kubernetes_name":"kube-state-metrics","kubernetes_namespace":"monitor","namespace":"test-mars","pod":"emqx-test-0"},"commonAnnotations":{},"externalURL":"https://xalertmanager-dev.i-tetris.com","version":"4","groupKey":"{}/{job=~\"^(?:.*)$\"}:{instance=\"172.28.58.250:8080\"}"}
wxurl:=c.GetString("wxurl")
ddurl:=c.GetString("ddurl")
phone:=c.GetString("phone")
fmt.Println(phone)
alert:=Prometheus{}
log.SetPrefix("[DEBUG 1]")
log.Println(string(c.Ctx.Input.RequestBody))
json.Unmarshal(c.Ctx.Input.RequestBody, &alert)
c.Data["json"]=SendMessageR(alert,wxurl,ddurl,phone)
log.SetPrefix("[DEBUG 3]")
log.Println(c.Data["json"])
c.ServeJSON()
}

func SendMessageR(message Prometheus,rwxurl,rddurl,rphone string)(string) {
Title:=beego.AppConfig.String("title")
Logourl:=beego.AppConfig.String("logourl")
Messagelevel,_:=beego.AppConfig.Int("messagelevel")
PhoneCalllevel,_:=beego.AppConfig.Int("phonecalllevel")
PhoneCallResolved,_:=beego.AppConfig.Int("phonecallresolved")
Silent,_:=beego.AppConfig.Int("silent")
var ddtext,wxtext,MobileMessage,PhoneCallMessage,titleend,returnMessage string
//对分组消息进行排序
AlerMessage:=message.Alerts
sort.Sort(AlerMessages(AlerMessage))
//告警级别定义 0 信息,1 警告,2 一般严重,3 严重,4 灾难
AlertLevel:=[]string{"信息","警告","一般严重","严重","灾难"}
//遍历消息
for _, RMessage := range AlerMessage {
nLevel,_:=strconv.Atoi(RMessage.Labels.Level)
if RMessage.Status=="resolved" {
titleend="故障恢复信息"
ddtext="## ["+Title+"Prometheus"+titleend+"]("+RMessage.GeneratorUrl+")\n\n"+"#### ["+RMessage.Labels.Alertname+"]("+message.Externalurl+")\n\n"+"###### 告警级别:"+AlertLevel[nLevel]+"\n\n"+"###### 开始时间:"+RMessage.StartsAt+"\n\n"+"###### 结束时间:"+RMessage.EndsAt+"\n\n"+"###### 故障主机IP:"+RMessage.Labels.Instance+"\n\n"+"##### "+RMessage.Annotations.Description+"\n\n"+"!["+Title+"]("+Logourl+")"
wxtext="["+Title+"Prometheus"+titleend+"]("+RMessage.GeneratorUrl+")\n>**["+RMessage.Labels.Alertname+"]("+message.Externalurl+")**\n>`告警级别:`"+AlertLevel[nLevel]+"\n`开始时间:`"+RMessage.StartsAt+"\n`结束时间:`"+RMessage.EndsAt+"\n`故障主机IP:`"+RMessage.Labels.Instance+"\n**"+RMessage.Annotations.Description+"**"
MobileMessage="\n["+Title+"Prometheus"+titleend+"]\n"+RMessage.Labels.Alertname+"\n"+"告警级别:"+AlertLevel[nLevel]+"\n"+"开始时间:"+RMessage.StartsAt+"\n"+"结束时间:"+RMessage.EndsAt+"\n"+"故障主机IP:"+RMessage.Labels.Instance+"\n"+RMessage.Annotations.Description
PhoneCallMessage="故障主机IP:"+RMessage.Labels.Instance+","+RMessage.Annotations.Description+"已经恢复"
}else {
titleend="故障告警信息"
ddtext="## ["+Title+"Prometheus"+titleend+"]("+RMessage.GeneratorUrl+")\n\n"+"#### ["+RMessage.Labels.Alertname+"]("+message.Externalurl+")\n\n"+"###### 告警级别:"+AlertLevel[nLevel]+"\n\n"+"###### 开始时间:"+RMessage.StartsAt+"\n\n"+"###### 结束时间:"+RMessage.EndsAt+"\n\n"+"###### 故障主机IP:"+RMessage.Labels.Instance+"\n\n"+"##### "+RMessage.Annotations.Description+"\n\n"+"!["+Title+"]("+Logourl+")"
wxtext="["+Title+"Prometheus"+titleend+"]("+RMessage.GeneratorUrl+")\n>**["+RMessage.Labels.Alertname+"]("+message.Externalurl+")**\n>`告警级别:`"+AlertLevel[nLevel]+"\n`开始时间:`"+RMessage.StartsAt+"\n`结束时间:`"+RMessage.EndsAt+"\n`故障主机IP:`"+RMessage.Labels.Instance+"\n**"+RMessage.Annotations.Description+"**"
MobileMessage="\n["+Title+"Prometheus"+titleend+"]\n"+RMessage.Labels.Alertname+"\n"+"告警级别:"+AlertLevel[nLevel]+"\n"+"开始时间:"+RMessage.StartsAt+"\n"+"结束时间:"+RMessage.EndsAt+"\n"+"故障主机IP:"+RMessage.Labels.Instance+"\n"+RMessage.Annotations.Description
PhoneCallMessage="故障主机IP:"+RMessage.Labels.Instance+","+RMessage.Annotations.Description
}
//发送消息到钉钉
if rddurl==""{
url:=beego.AppConfig.String("ddurl")
returnMessage = returnMessage + "PostToDingDing:" + PostToDingDing(Title+titleend, ddtext, url) + "\n"
}else {
returnMessage = returnMessage + "PostToDingDing:" + PostToDingDing(Title+titleend, ddtext, rddurl) + "\n"
}
//发送消息到微信
if rwxurl=="" {
url := beego.AppConfig.String("wxurl")
returnMessage = returnMessage + "PostToWeiXin:" + PostToWeiXin(wxtext, url) + "\n"
}else {
returnMessage = returnMessage + "PostToWeiXin:" + PostToWeiXin(wxtext, rwxurl) + "\n"
}
//发送消息到短信
if (nLevel==Messagelevel) {
if rphone=="" {
phone:=GetUserPhone(1)
returnMessage = returnMessage + "PostTXmessage:" + PostTXmessage(MobileMessage, phone) + "\n"
returnMessage = returnMessage + "PostHWmessage:" + PostHWmessage(MobileMessage, phone) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostALYmessage(MobileMessage, phone) + "\n"
}else {
returnMessage = returnMessage + "PostTXmessage:" + PostTXmessage(MobileMessage, rphone) + "\n"
returnMessage = returnMessage + "PostHWmessage:" + PostHWmessage(MobileMessage, rphone) + "\n"
returnMessage = returnMessage + "PostALYmessage:" + PostALYmessage(MobileMessage, rphone) + "\n"
}
}
//发送消息到语音
if (nLevel==PhoneCalllevel) {
//判断如果是恢复信息且PhoneCallResolved
if (RMessage.Status=="resolved" && PhoneCallResolved!=1) {
returnMessage="告警恢复消息已经关闭\n"
}else {
if rphone=="" {
phone:=GetUserPhone(1)
returnMessage = returnMessage + "PostTXphonecall:" + PostTXphonecall(PhoneCallMessage, phone) + "\n"
returnMessage = returnMessage + "PostALYphonecall:" + PostALYphonecall(PhoneCallMessage, phone) + "\n"
}else {
returnMessage = returnMessage + "PostTXphonecall:" + PostTXphonecall(PhoneCallMessage, rphone) + "\n"
returnMessage = returnMessage + "PostALYphonecall:" + PostALYphonecall(PhoneCallMessage, rphone) + "\n"
}
}
}
//告警抑制开启就直接跳出循环
if Silent==1 {
break
}
}
return returnMessage
}

Binary file modified doc/dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions example/helm/prometheusalert/config/app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ silent=1
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=1

#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
Expand Down
4 changes: 3 additions & 1 deletion example/kubernetes/PrometheusAlert-Deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ data:
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=1
#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
#默认企业微信机器人地址
Expand Down
Binary file modified example/linux/PrometheusAlert
Binary file not shown.
2 changes: 2 additions & 0 deletions example/linux/conf/app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ silent=1
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=1

#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
Expand Down
Binary file added example/linux/static/img/prometheus-ico.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
58 changes: 38 additions & 20 deletions example/linux/views/index.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,27 @@
header,
.footer {
width: 960px;
width: 100%;
margin-left: auto;
margin-right: auto;
text-align:center;
}
.logo {
background-image: url('https://avatars1.githubusercontent.com/u/3380462?s=200&v=4');
background-image: url('/static/img/prometheus-ico.png');
background-repeat: no-repeat;
-webkit-background-size: 100px 100px;
background-size: 100px 100px;
background-position: center center;
-webkit-background-size: 70px 70px;
background-size: 70px 70px;
background-position: center top;
text-align: center;
font-size: 42px;
padding: 200px 0 20px;
font-size: 32px;
padding: 100px 0 10px;
font-weight: normal;
text-shadow: 0px 1px 2px #ddd;
}
.box {
text-align: center;
font-size: 16px;
height: 100px;
height: 200px;
}
.description {
text-align: center;
Expand All @@ -57,7 +56,7 @@
.backdrop {
position: absolute;
width: 100%;
height: 100%;
height: 500px;
box-shadow: inset 0px 0px 100px #ddd;
z-index: -1;
top: 0px;
Expand All @@ -68,22 +67,41 @@
<body class="backdrop">
<header>
<h1 class="logo">Welcome to Prometheus Alert System</h1>
</header>

<div class="box">
<p>PS:短信测试和电话测试请提前配置好app.conf中的[defaultphone]配置项</p>
<button class="btn btn-primary" data-toggle='modal' id="dd">钉钉告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="wx">微信告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="txdx">腾讯云短信告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="txdh">腾讯云电话告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="hwdx">华为云短信告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="alydx">阿里云短信告警测试</button>
<button class="btn btn-primary" data-toggle='modal' id="alydh">阿里云电话告警测试</button>
<table border="0" style="width: 60%;margin:auto;text-shadow: 0px 1px 2px #ddd;">
<tr>
<td><p>webhook</p></td>
<td><p>短信</p></td>
<td><p>电话</p></td>
</tr>
<tr>
<td><p><button class="btn btn-primary" data-toggle='modal' id="dd">钉钉告警测试</button></p></td>
<td><p><button class="btn btn-primary" data-toggle='modal' id="hwdx">华为云短信告警测试</button></p></td>
<td><p><button class="btn btn-primary" data-toggle='modal' id="txdh">腾讯云电话告警测试</button></p></td>
</tr>
<tr>
<td><p><button class="btn btn-primary" data-toggle='modal' id="wx">微信告警测试</button></p></td>
<td><p><button class="btn btn-primary" data-toggle='modal' id="txdx">腾讯云短信告警测试</button></p></td>
<td><p><button class="btn btn-primary" data-toggle='modal' id="alydh">阿里云电话告警测试</button></p></td>
</tr>
<tr>
<td></td>
<td><p><button class="btn btn-primary" data-toggle='modal' id="alydx">阿里云短信告警测试</button></p></td>
<td></td>
</tr>
<tr>
<td colspan="3"><p>PS:短信测试和电话测试请提前配置好app.conf中的[defaultphone]配置项</p></td>
</tr>
</table>
</div>
<div class="description">
<a href="https://github.com/feiyu563/PrometheusAlert">Go to My GitHub and find how to use it or get new version !</a>
<a href="https://feiyu563.github.io">Go to My GitHub and find how to use it or get new version !</a>
<p> Contact me: </p>
<p> <img height="10%" width="10%" src="/static/img/wx.png" /> </p>
</div>
</header>
<script src="/static/js/reload.min.js"></script>
<script>
$(function(){
Expand Down
Binary file modified example/windows/PrometheusAlert.exe
Binary file not shown.
2 changes: 2 additions & 0 deletions example/windows/conf/app.conf
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ silent=1
open-dingding=1
#默认钉钉机器人地址
ddurl=https://oapi.dingtalk.com/robot/send?access_token=xxxxx
#是否开启 @所有人(0为关闭,1为开启)
dd_isatall=1

#是否开启微信告警通道,可同时开始多个通道0为关闭,1为开启
open-weixin=1
Expand Down
Binary file added example/windows/static/img/prometheus-ico.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit f84045d

Please sign in to comment.