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\"}" +} +```