diff --git a/Makefile b/Makefile
index e1e95742..fe4df78f 100644
--- a/Makefile
+++ b/Makefile
@@ -1,19 +1,18 @@
SHELL:=/bin/sh
-.PHONY: all vet test build clean docker docker-push docker-test
+.PHONY: all format vet test build clean docker docker-push docker-test
export GO111MODULE=on
export GOPROXY=https://goproxy.io
+pkgs = $(shell go list ./... | grep -v vendor/)
+
# path related
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
-MKFILE_DIR := $(dir $(MKFILE_PATH))
-RELEASE_DIR := ${MKFILE_DIR}/build/bin
-
-pkgs = $(shell go list ./... | grep -v vendor/)
+MKFILE_DIR := $(dir $(MKFILE_PATH))
DOCKER_IMAGE_NAME ?= feiyu563/prometheus-alert
-BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
+BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
BUILDDATE ?= $(shell date -I'seconds')
BUILDUSER ?= $(shell whoami)@$(shell hostname)
REVISION ?= $(shell git rev-parse HEAD)
@@ -26,8 +25,8 @@ VERSION_LDFLAGS := \
-X main.BuildDate=$(BUILDDATE)
# go source files, ignore vendor directory
-SOURCE = $(shell find ${MKFILE_DIR} -type f -name "*.go")
-TARGET = ${RELEASE_DIR}/PrometheusAlert
+SOURCE = $(shell find ${MKFILE_DIR} -path "${MKFILE_DIR}vendor" -prune -o -type f -name "*.go" -print)
+TARGET = ${MKFILE_DIR}/PrometheusAlert
all: ${TARGET}
@@ -35,7 +34,6 @@ ${TARGET}: ${SOURCE}
@echo ">> building code"
go mod tidy
go mod vendor
- mkdir -p ${RELEASE_DIR}
go build -ldflags "$(VERSION_LDFLAGS)" -o ${TARGET}
format:
@@ -54,7 +52,7 @@ build: all
clean:
@echo ">> cleaning build"
- rm -rf ${MKFILE_DIR}build
+ rm ${TARGET}
docker:
@echo ">> building docker image"
diff --git a/conf/app-example.conf b/conf/app-example.conf
index f44a8bac..183f8c50 100644
--- a/conf/app-example.conf
+++ b/conf/app-example.conf
@@ -281,15 +281,6 @@ AT_USER_ID="xxxxxxxx"
# 是否启用告警组功能
open-alertgroup=0
-# demo 告警组,用于测试案例测试
-[ag-demo]
-wxurl=wxurl1,wxurl2
-ddurl=ddurl1,ddurl1,
-fsurl=fsurl1
-email=email1,
-phone=phone1,phone2
-groupid=groupid1
-
# 自定义的告警组既可以写在这里,也可以写在单独的文件里。
# 写在单独的告警组配置里更便于修改。
-include "alertgroup.conf"
+# include "alertgroup.conf"
diff --git a/conf/prometheus-demo.json b/conf/prometheus-demo.json
deleted file mode 100644
index 5bf31d2e..00000000
--- a/conf/prometheus-demo.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "status": "firing",
- "alerts": [
- {
- "status": "firing",
- "labels": {
- "alertname": "TestAlert",
- "instance": "localhost",
- "level": "1",
- "severity": "warning",
- "job": "node_exporter",
- "hostgroup": "test",
- "hostname": "ecs01"
- },
- "annotations": {
- "description": "This is a test alert",
- "summary": "Test Alert Summary",
- "alertgroup": "sa,dev"
- },
- "startsAt": "2023-06-25T10:00:00Z",
- "endsAt": "2023-06-25T11:00:00Z",
- "generatorURL": "http://localhost/alerts"
- }
- ],
- "externalURL": "http://localhost/prometheus"
-}
\ No newline at end of file
diff --git a/controllers/prometheus.go b/controllers/prometheus.go
index d2f13ee4..6670caff 100644
--- a/controllers/prometheus.go
+++ b/controllers/prometheus.go
@@ -405,7 +405,9 @@ func Alertgroup(alertgroup string) map[string]string {
}
ags := strings.Split(alertgroup, ",")
- var wxurl, ddurl, fsurl, email, phone, groupid string
+ // url likes: url1,url2...
+ var wxurl, ddurl, fsurl, email, phone, groupid, webhookurl string
+
// Assembling multiple alertgroups of url together
for _, v := range ags {
wxurl = wxurl + "," + beego.AppConfig.String(v+"::wxurl")
@@ -414,15 +416,17 @@ func Alertgroup(alertgroup string) map[string]string {
phone = phone + "," + beego.AppConfig.String(v+"::phone")
email = email + "," + beego.AppConfig.String(v+"::email")
groupid = groupid + "," + beego.AppConfig.String(v+"::groupid")
+ webhookurl = webhookurl + "," + beego.AppConfig.String(v+"::webhookurl")
}
agMap = map[string]string{
- "wxurl": URLDeduplication(wxurl),
- "ddurl": URLDeduplication(ddurl),
- "fsurl": URLDeduplication(fsurl),
- "phone": URLDeduplication(phone),
- "email": URLDeduplication(email),
- "groupid": URLDeduplication(groupid),
+ "wxurl": URLDeduplication(wxurl),
+ "ddurl": URLDeduplication(ddurl),
+ "fsurl": URLDeduplication(fsurl),
+ "phone": URLDeduplication(phone),
+ "email": URLDeduplication(email),
+ "groupid": URLDeduplication(groupid),
+ "webhookurl": URLDeduplication(webhookurl),
}
return agMap
@@ -438,6 +442,8 @@ func URLDeduplication(url string) string {
uniqueMap := make(map[string]bool)
for _, s := range urlSlice {
+ // Remove space at the begin or end.
+ s = strings.TrimSpace(s)
uniqueMap[s] = true
}
@@ -455,3 +461,13 @@ func URLDeduplication(url string) string {
return newURL
}
+
+// checkURL checks urls and return non-nil url
+func checkURL(urls ...string) string {
+ for _, url := range urls {
+ if len(strings.TrimSpace(url)) != 0 {
+ return url
+ }
+ }
+ return ""
+}
diff --git a/controllers/prometheus_test.go b/controllers/prometheus_test.go
index b5703bf1..59dc55fc 100644
--- a/controllers/prometheus_test.go
+++ b/controllers/prometheus_test.go
@@ -2,21 +2,13 @@ package controllers
import (
"encoding/json"
- "path/filepath"
- "runtime"
+ "os"
"testing"
"github.com/astaxie/beego"
"github.com/stretchr/testify/assert"
)
-// Load app conf
-func init() {
- _, file, _, _ := runtime.Caller(0)
- apppath, _ := filepath.Abs(filepath.Dir(filepath.Join(file, ".."+string(filepath.Separator))))
- beego.TestBeegoInit(apppath)
-}
-
func TestURLDeduplication(t *testing.T) {
assert := assert.New(t)
var want, result string
@@ -25,16 +17,40 @@ func TestURLDeduplication(t *testing.T) {
result = URLDeduplication("")
assert.Equal(want, result)
- want = "ag0-wxurl0,ag0-wxurl1"
- result = URLDeduplication("ag0-wxurl0,ag0-wxurl1")
+ want = "sa-wxurl0"
+ result = URLDeduplication("sa-wxurl0")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0"
+ result = URLDeduplication("sa-wxurl0,")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0"
+ result = URLDeduplication(",sa-wxurl0")
assert.Equal(want, result)
- want = "ag0-wxurl0,ag0-wxurl1"
- result = URLDeduplication("ag0-wxurl0,ag0-wxurl1,")
+ want = "sa-wxurl0"
+ result = URLDeduplication(",sa-wxurl0,")
assert.Equal(want, result)
- want = "ag0-wxurl0,ag0-wxurl1"
- result = URLDeduplication("ag0-wxurl0,ag0-wxurl1,ag0-wxurl0,ag0-wxurl1")
+ want = "sa-wxurl0"
+ result = URLDeduplication("sa-wxurl0, ")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0,sa-wxurl1"
+ result = URLDeduplication("sa-wxurl0,sa-wxurl1")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0,sa-wxurl1"
+ result = URLDeduplication("sa-wxurl0, sa-wxurl1")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0,sa-wxurl1"
+ result = URLDeduplication("sa-wxurl0,sa-wxurl1, ")
+ assert.Equal(want, result)
+
+ want = "sa-wxurl0,sa-wxurl1"
+ result = URLDeduplication("sa-wxurl0,sa-wxurl1,sa-wxurl0,sa-wxurl1")
assert.Equal(want, result)
}
@@ -42,25 +58,85 @@ func TestAlertgroup(t *testing.T) {
assert := assert.New(t)
var want, result map[string]string
+ // tempFile is /tmp/app*.conf
+ tempFile, err := os.CreateTemp("", "app*.conf")
+ defer tempFile.Close()
+ defer os.Remove(tempFile.Name())
+ assert.Nil(err)
+
+ // mock app.conf
+ configData := `
+ [sa]
+ wxurl=wxurl1
+ ddurl=ddurl1,
+ fsurl=,fsurl1
+ email=,email1,
+ phone=phone1,phone1
+ groupid=groupid1,groupid1,
+ [ops]
+ wxurl=wxurl1,wxurl2
+ ddurl=ddurl1,ddurl2,
+ fsurl=,fsurl1,fsurl2
+ email=,email1,email2,
+ phone=phone2
+ groupid=groupid2
+ [customtpl]
+ wxurl=wxurl1,wxurl2
+ ddurl=ddurl1,ddurl2
+ fsurl=fsurl1,fsurl2
+ email=email1,email2
+ phone=phone1,phone2
+ groupid=groupid1,groupid2
+ webhookurl=webhookurl1,webhookurl2
+ `
+
+ // Write mock conf into tempFile
+ _, err = tempFile.Write([]byte(configData))
+ assert.Nil(err)
+
+ beego.InitBeegoBeforeTest(tempFile.Name())
+
result = Alertgroup("")
assert.Equal(want, result)
- open := beego.AppConfig.String("open-alertgroup")
- if open == "1" {
- result = Alertgroup("ag-demo")
- want = map[string]string{
- "wxurl": "wxurl1,wxurl2",
- "ddurl": "ddurl1",
- "fsurl": "fsurl1",
- "phone": "phone1,phone2",
- "email": "email1",
- "groupid": "groupid1",
- }
- assert.Equal(want, result)
+ want = map[string]string{
+ "wxurl": "wxurl1",
+ "ddurl": "ddurl1",
+ "fsurl": "fsurl1",
+ "phone": "phone1",
+ "email": "email1",
+ "groupid": "groupid1",
+ "webhookurl": "",
+ }
+ result = Alertgroup("sa")
+ assert.Equal(want, result)
+
+ want = map[string]string{
+ "wxurl": "wxurl1,wxurl2",
+ "ddurl": "ddurl1,ddurl2",
+ "fsurl": "fsurl1,fsurl2",
+ "email": "email1,email2",
+ "phone": "phone1,phone2",
+ "groupid": "groupid1,groupid2",
+ "webhookurl": "",
}
+ result = Alertgroup("sa,ops")
+ assert.Equal(want, result)
+
+ want = map[string]string{
+ "wxurl": "wxurl1,wxurl2",
+ "ddurl": "ddurl1,ddurl2",
+ "fsurl": "fsurl1,fsurl2",
+ "email": "email1,email2",
+ "phone": "phone1,phone2",
+ "groupid": "groupid1,groupid2",
+ "webhookurl": "webhookurl1,webhookurl2",
+ }
+ result = Alertgroup("customtpl")
+ assert.Equal(want, result)
}
-func TestPrometheus(t *testing.T) {
+func TestPrometheusJSON(t *testing.T) {
// A sample prometheus alertmanager JSON payload
payload := `
{
@@ -92,7 +168,30 @@ func TestPrometheus(t *testing.T) {
alert := Prometheus{}
err := json.Unmarshal([]byte(payload), &alert)
- if err != nil {
- t.Errorf("Prometheus alertmanager json payload parse error: %s", err)
- }
+ assert.Nil(t, err)
+}
+
+func TestCheckURL(t *testing.T) {
+ assert := assert.New(t)
+ var want, result string
+
+ want = ""
+ result = checkURL("", "")
+ assert.Equal(want, result)
+
+ want = "url1"
+ result = checkURL("url1", "", "")
+ assert.Equal(want, result)
+
+ want = "url2"
+ result = checkURL("", "url2", "")
+ assert.Equal(want, result)
+
+ want = "url3"
+ result = checkURL("", "", "url3")
+ assert.Equal(want, result)
+
+ want = "url1"
+ result = checkURL("url1", "url2", "url3")
+ assert.Equal(want, result)
}
diff --git a/controllers/prometheusalert.go b/controllers/prometheusalert.go
index 8e46c69b..030bd52c 100644
--- a/controllers/prometheusalert.go
+++ b/controllers/prometheusalert.go
@@ -5,14 +5,15 @@ import (
"PrometheusAlert/models/elastic"
"bytes"
"encoding/json"
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/logs"
tmplhtml "html/template"
"regexp"
"strconv"
"strings"
"text/template"
"time"
+
+ "github.com/astaxie/beego"
+ "github.com/astaxie/beego/logs"
)
type PrometheusAlertController struct {
@@ -110,50 +111,43 @@ func (c *PrometheusAlertController) PrometheusAlert() {
json.Unmarshal(c.Ctx.Input.RequestBody, &p_alertmanager_json)
}
+ // alertgroup
+ alertgroup := c.Input().Get("alertgroup")
+ openAg := beego.AppConfig.String("open-alertgroup")
+ var agMap map[string]string
+ if openAg == "1" && len(alertgroup) != 0 {
+ agMap = Alertgroup(alertgroup)
+ }
+
pMsg.Type = c.Input().Get("type")
pMsg.Tpl = c.Input().Get("tpl")
- pMsg.Ddurl = c.Input().Get("ddurl")
- if pMsg.Ddurl == "" {
- pMsg.Ddurl = beego.AppConfig.String("ddurl")
- }
- pMsg.Wxurl = c.Input().Get("wxurl")
- if pMsg.Wxurl == "" {
- pMsg.Wxurl = beego.AppConfig.String("wxurl")
- }
- pMsg.Fsurl = c.Input().Get("fsurl")
- if pMsg.Fsurl == "" {
- pMsg.Fsurl = beego.AppConfig.String("fsurl")
- }
- pMsg.WebHookUrl = c.Input().Get("webhookurl")
- pMsg.WebhookContentType = c.Input().Get("webhookContentType")
- pMsg.Phone = c.Input().Get("phone")
+
+ // 告警组适合处理以逗号分隔的多个值
+ pMsg.Ddurl = checkURL(agMap["ddurl"], c.Input().Get("ddurl"), beego.AppConfig.String("ddurl"))
+ pMsg.Wxurl = checkURL(agMap["wxurl"], c.Input().Get("wxurl"), beego.AppConfig.String("wxurl"))
+ pMsg.Fsurl = checkURL(agMap["fsurl"], c.Input().Get("fsurl"), beego.AppConfig.String("fsurl"))
+ pMsg.Email = checkURL(agMap["email"], c.Input().Get("email"), beego.AppConfig.String("fsurl"))
+ pMsg.GroupId = checkURL(agMap["groupid"], c.Input().Get("groupid"), beego.AppConfig.String("BDRL_ID"))
+
+ pMsg.Phone = checkURL(agMap["phone"], c.Input().Get("phone"))
if pMsg.Phone == "" && (pMsg.Type == "txdx" || pMsg.Type == "hwdx" || pMsg.Type == "bddx" || pMsg.Type == "alydx" || pMsg.Type == "txdh" || pMsg.Type == "alydh" || pMsg.Type == "rlydh" || pMsg.Type == "7moordx" || pMsg.Type == "7moordh") {
pMsg.Phone = GetUserPhone(1)
}
- pMsg.Email = c.Input().Get("email")
- if pMsg.Email == "" {
- pMsg.Email = beego.AppConfig.String("Default_emails")
- }
- pMsg.ToUser = c.Input().Get("wxuser")
- if pMsg.ToUser == "" {
- pMsg.ToUser = beego.AppConfig.String("WorkWechat_ToUser")
- }
- pMsg.ToParty = c.Input().Get("wxparty")
- if pMsg.ToParty == "" {
- pMsg.ToParty = beego.AppConfig.String("WorkWechat_ToParty")
- }
- pMsg.ToTag = c.Input().Get("wxtag")
- if pMsg.ToTag == "" {
- pMsg.ToTag = beego.AppConfig.String("WorkWechat_ToTag")
- }
- pMsg.GroupId = c.Input().Get("groupid")
- if pMsg.GroupId == "" {
- pMsg.GroupId = beego.AppConfig.String("BDRL_ID")
- }
+
+ pMsg.WebHookUrl = checkURL(agMap["webhookurl"], c.Input().Get("webhookurl"))
+ // webhookContenType, rr, split, workwechat 是单个值,因此不写入告警组。
+ pMsg.WebhookContentType = c.Input().Get("webhookContentType")
+
+ pMsg.ToUser = checkURL(c.Input().Get("wxuser"), beego.AppConfig.String("WorkWechat_ToUser"))
+ pMsg.ToParty = checkURL(c.Input().Get("wxparty"), beego.AppConfig.String("WorkWechat_ToUser"))
+ pMsg.ToTag = checkURL(c.Input().Get("wxtag"), beego.AppConfig.String("WorkWechat_ToUser"))
+
+ // dd, wx, fsv2 的 at 格式不一样,放在告警组里不好处理和组装。
pMsg.AtSomeOne = c.Input().Get("at")
pMsg.RoundRobin = c.Input().Get("rr")
//该配置仅适用于alertmanager的消息,用于判断是否需要拆分alertmanager告警消息
pMsg.Split = c.Input().Get("split")
+
//模版加载进内存处理,防止告警过多频繁查库
var PrometheusAlertTpl *models.PrometheusAlertDB
if GlobalPrometheusAlertTpl == nil {
@@ -222,7 +216,7 @@ func (c *PrometheusAlertController) PrometheusAlert() {
c.ServeJSON()
}
-//路由处理
+// 路由处理
func AlertRouterSet(xalert map[string]interface{}, PMsg PrometheusAlertMsg, Tpl string) []PrometheusAlertMsg {
return_Msgs := []PrometheusAlertMsg{}
//原有的参数不变
@@ -308,7 +302,7 @@ func AlertRouterSet(xalert map[string]interface{}, PMsg PrometheusAlertMsg, Tpl
return return_Msgs
}
-//处理告警记录
+// 处理告警记录
func SetRecord(AlertValue interface{}) {
var Alertname, Status, Level, Labels, Instance, Summary, Description, StartAt, EndAt string
xalert := AlertValue.(map[string]interface{})
@@ -382,7 +376,7 @@ func SetRecord(AlertValue interface{}) {
}
}
-//消息模版化
+// 消息模版化
func TransformAlertMessage(p_json interface{}, tpltext string) (error error, msg string) {
funcMap := template.FuncMap{
"GetCSTtime": GetCSTtime,
@@ -430,7 +424,7 @@ func TransformAlertMessage(p_json interface{}, tpltext string) (error error, msg
return nil, buf.String()
}
-//发送消息
+// 发送消息
func SendMessagePrometheusAlert(message string, pmsg *PrometheusAlertMsg, logsign string) string {
Title := beego.AppConfig.String("title")
var ReturnMsg string
diff --git a/doc/readme/alertgroup.md b/doc/readme/alertgroup.md
index 110d6476..c14191f8 100644
--- a/doc/readme/alertgroup.md
+++ b/doc/readme/alertgroup.md
@@ -7,13 +7,21 @@
## 告警组介绍
-由于之前是使用配置文件里默认的通知媒介地址(`wxurl, ddurl...`),或自定义的写在 prometheus rule annotations 的地址。修改这个自定义告警地址很麻烦,虽然也可以使用 `vim` 或 `sed` 命令来批量操作。
+> **注意**:
+> 告警组功能适合以逗号隔开的地址,组装这一类的地址。
+> 自定义模板中的 模板类型(type)、模板(tpl)、webhookContentType、企微应用、at、rr、split等,便不太适合写入告警组,因此这里并没有处理这些值,还是按照原来写在URL参数上。
+
+
借鉴了云平台监控的告警通知组这个功能,将自定义地址都配置到告警组,然后配置不同的告警组(如 sa, dev...)。通过 beego 框架配置文件的 section 功能,将不同的告警组配置为不同的 section。
编写一个函数从配置文件中取出这些地址,并将其去重和汇总,然后以一个包含了特定类型地址的变量传递给发送消息的函数。
-目前告警组功能仅支持 `/prometheus/alert` 这个旧控制器里面的接口,暂不涉及到自定义模板的接口 `/prometheusalert`。
+旧接口,之前是使用配置文件里默认的通知媒介地址(`wxurl, ddurl...`),或自定义的写在 prometheus rule annotations 的地址。修改这个自定义告警地址很麻烦,虽然也可以使用 `vim` 或 `sed` 命令来批量操作。
+
+自定义模板接口,不必将很长的多个地址写到 URL,而只需要修改和配置 `app.conf` 文件,要方便一些。
+
+旧的接口 `/prometheus/alert` 和自定义模板接口 `/prometheusalert` 有一些不同,下面会介绍各自的用法。
@@ -32,15 +40,6 @@
# 是否启用告警组功能
open-alertgroup=1
-# demo 告警组,用于测试案例测试
-[ag-demo]
-wxurl=wxurl1,wxurl2
-ddurl=ddurl1,ddurl1,
-fsurl=fsurl1
-email=email1,
-phone=phone1,phone2
-groupid=groupid1
-
# sa 组
[ag-sa]
wxurl=wxurl1,wxurl2
@@ -51,37 +50,57 @@ phone=13x,15x
include "alertgroup.conf"
```
-`alertgroup.conf`:
+扩展的告警组配置文件 `alertgroup.conf`:
```conf
-# ops 组
+# ops 示例组
[ops]
ddurl=ddurl1,ddurl2
fsurl=fsurl1
phone=17x,18x
groupid=groupid1
-# dev 组
+# dev 示例组
[dev]
wxurl=wxurl3
ddurl=ddurl3
fsurl=fsurl3
phone=13x,17x,18x
+
+# 自定义模板告警组示例,目前仅处理了以下这些参数
+[customtpl]
+wxurl=wxurl1,wxurl2
+ddurl=ddurl1,ddurl2
+fsurl=fsurl1,fsurl2
+email=email1,email2
+phone=phone1,phone2
+groupid=groupid1,groupid2
+webhookurl=webhookurl1,webhookurl2
```
+
+
+
## 告警组使用
+
+
+### 旧接口 /prometheus/alert 的使用
+
注意:
+- 告警组并不影响原来的 annotations 或默认配置的使用。
- 如果 annotations 配置了告警组,但 `app.conf` 配置里未配置告警组,则会使用配置文件里默认的那个地址(wxurl, ddurl...)。
- 如果 annotations 配置了告警组,并且 `app.conf` 配置里有配置告警组,则会使用告警组里面的地址。
-- 每次修改通知地址,就只需要修改告警组里面的地址,而不用去修改 promtheus rules 的地址了。
+- 地址的判断先后顺序:告警组-annotations-配置文件,哪个有值使用哪个。
+- 每次修改通知地址,就只需要修改告警组里面的地址,而不用去修改 annotations 里的地址了。
-旧的 prometheus rule annotation 配置示例:
+annotations 示例:
```yml
+# 旧的 annotation 配置示例
annotations:
summary: "xxx"
description: "xxx"
@@ -91,9 +110,8 @@ annotations:
mobile: 13x,15x
```
-使用告警组的 prometheus rule annotations 配置示例:
-
```yml
+# 使用告警组的 prometheus rule annotations 配置示例
annotations:
summary: "xxx"
description: "xxx"
@@ -103,6 +121,119 @@ annotations:
+### 自定义模板接口 /prometheusalert 的使用
+
+注意:
+
+- 告警组并不影响原来的 URL 传递参数的使用。
+- 如果配置了告警组,且告警组中的地址不为空,则使用告警组中配置的地址。
+- 地址的判断先后顺序:告警组-URL参数-配置文件,哪个不为空使用哪个。
+- 自定义模板中的 模板类型(type)、模板(tpl)、webhookContentType、企微应用、at、rr、split等,便不太适合写入告警组,因此这里并没有处理这些值,还是按照原来写在URL参数上。
+- 在 URL 参数上配置 `alertgroup=xxx`,然后将具体的地址写到配置文件的告警组下面。
+
+自定义接口示例,这样在 alertmanager 或其它软件中接入地址的时候,就不需要带上很长的具体各个媒介的地址,而只需要写告警组就可以了。
+
+```txt
+# prometheus-dd
+http://127.0.0.1:8080/prometheusalert?type=dd&tpl=prometheus-dd&alertgroup=customtpl
+http://127.0.0.1:8080/prometheusalert?type=dd&tpl=prometheus-dd&alertgroup=customtpl&at=188xxx
+
+# prometheus-wx
+http://127.0.0.1:8080/prometheusalert?type=wx&tpl=prometheus-wx&alertgroup=sa,dev
+http://127.0.0.1:8080/prometheusalert?type=wx&tpl=prometheus-wx&alertgroup=sa&at=zhangsan
+
+# prometheus-fs
+http://127.0.0.1:8080/prometheusalert?type=fs&tpl=prometheus-fs&&alertgroup=sa&at=zhangsan@xxx.com
+
+# 其它效果类似
+# 可以通过下面的测试告警组文档先测试效果
+```
+
+
+
+
## 调试告警组
-文件 `conf/prometheus-demo.json` 是一个 prometheus 告警信息的示例 json 内容。我们可以通过修改此 json,然后通过 postman 将自定义的告警消息发送到接口 (`http://127.0.0.1:8080/prometheus/alert`),来调试告警组和通知消息等。
+通过下面的示例 JSON 内容,在 postman 将示例告警内容发送到接口进行测试。
+
+旧接口 (`http://127.0.0.1:8080/prometheus/alert`) 的示例告警 JSON 内容:
+
+```json
+{
+ "receiver": "prometheus-alert-center",
+ "status": "firing",
+ "alerts": [
+ {
+ "status": "firing",
+ "labels": {
+ "alertname": "TestAlert",
+ "instance": "localhost",
+ "level": "1",
+ "severity": "warning",
+ "job": "node_exporter",
+ "hostgroup": "test",
+ "hostname": "ecs01"
+ },
+ "annotations": {
+ "description": "This is a test alert",
+ "summary": "Test Alert Summary",
+ "alertgroup": "sa,dev"
+ },
+ "startsAt": "2023-06-25T10:00:00Z",
+ "endsAt": "2023-06-25T11:00:00Z",
+ "generatorURL": "http://localhost/alerts"
+ }
+ ],
+ "externalURL": "http://localhost/prometheus"
+}
+```
+
+
+
+自定义接口(`http://127.0.0.1:8080/prometheusalert?type=xx&tpl=xxx&alertgroup=xxx`)的示例告警 JSON 内容:
+
+```json
+{
+ "receiver": "prometheus-alert-center",
+ "status": "firing",
+ "alerts": [{
+ "status": "firing",
+ "labels": {
+ "alertname": "TargetDown",
+ "index": "1",
+ "instance": "example-1",
+ "job": "example",
+ "level": "2",
+ "service": "example"
+ },
+ "annotations": {
+ "description": "target was down! example dev /example-1 was down for more than 120s.",
+ "level": "2",
+ "timestamp": "2020-05-21 02:58:07.829 +0000 UTC"
+ },
+ "startsAt": "2020-05-21T02:58:07.830216179Z",
+ "endsAt": "0001-01-01T00:00:00Z",
+ "generatorURL": "https://prometheus-alert-center/graph?g0.expr=up%7Bjob%21%3D%22kubernetes-pods%22%2Cjob%21%3D%22kubernetes-service-endpoints%22%7D+%21%3D+1\u0026g0.tab=1",
+ "fingerprint": "e2a5025853d4da64"
+ }],
+ "groupLabels": {
+ "instance": "example-1"
+ },
+ "commonLabels": {
+ "alertname": "TargetDown",
+ "index": "1",
+ "instance": "example-1",
+ "job": "example",
+ "level": "2",
+ "service": "example"
+ },
+ "commonAnnotations": {
+ "description": "target was down! example dev /example-1 was down for more than 120s.",
+ "level": "2",
+ "timestamp": "2020-05-21 02:58:07.829 +0000 UTC"
+ },
+ "externalURL": "https://prometheus-alert-center",
+ "version": "4",
+ "groupKey": "{}/{job=~\"^(?:.*)$\"}:{instance=\"example-1\"}"
+}
+```