Skip to content

Commit

Permalink
Merge pull request #330 from Zhang21/feat-alertgroup
Browse files Browse the repository at this point in the history
Feat: add alertgroup
  • Loading branch information
feiyu563 committed Aug 28, 2023
2 parents b0cc463 + 9176aee commit f6b1dfe
Show file tree
Hide file tree
Showing 1,596 changed files with 671 additions and 757,938 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
conf/app.conf
conf/alertgroup.conf
PrometheusAlert
PrometheusAlert.exe
logo
.idea
logs/
example/linux
example/windows
vendor
old_delete/
vendor/
old_delete/
build/*
.vscode/
42 changes: 27 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
SHELL:=/bin/sh
.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))

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)
Expand All @@ -14,44 +24,46 @@ VERSION_LDFLAGS := \
-X main.BuildUser=$(BUILDUSER) \
-X main.BuildDate=$(BUILDDATE)

all: format vet test build
# go source files, ignore vendor directory
SOURCE = $(shell find ${MKFILE_DIR} -path "${MKFILE_DIR}vendor" -prune -o -type f -name "*.go" -print)
TARGET = ${MKFILE_DIR}/PrometheusAlert

all: ${TARGET}

${TARGET}: ${SOURCE}
@echo ">> building code"
go mod tidy
go mod vendor
go build -ldflags "$(VERSION_LDFLAGS)" -o ${TARGET}

.PHONY: format
format:
@echo ">> formatting code"
go fmt $(pkgs)

.PHONY: vet
vet:
@echo ">> vetting code"
go vet $(pkgs)

.PHONY: test
test:
@echo ">> running short tests"
go test -short $(pkgs)

.PHONY: build
build:
@echo ">> building code"
go mod tidy
go mod vendor
GO11MODULE=on GO111MODULE=on GOPROXY=https://goproxy.io \
go build -ldflags "$(VERSION_LDFLAGS)" -o PrometheusAlert
build: all

clean:
@echo ">> cleaning build"
rm ${TARGET}

.PHONY: docker
docker:
@echo ">> building docker image"
docker build -t "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" .
docker tag "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" "$(DOCKER_IMAGE_NAME):latest"

.PHONY: docker-push
docker-push:
@echo ">> pushing docker image"
docker push "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)"
docker push "$(DOCKER_IMAGE_NAME):latest"

.PHONY: docker-test
docker-test:
@echo ">> testing docker image and PrometheusAlert's health"
cmd/test_image.sh "$(DOCKER_IMAGE_NAME):$(TAG_VERSION)" 8080
43 changes: 22 additions & 21 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -34,44 +34,39 @@ PrometheusAlert是开源的运维告警中心消息转发系统,支持主流

应用信息和构建相关的命令都写入了Makefile,请确保安装`make`, `git`, `go`命令。如有特定需要,请自行修改Makefile。

```bash
```sh
# 默认
make

# 只运行构建
# 构建
make build

# 运行 go fmt
make format
# 清理构建
make clean

# 运行 go vet
make vet
# 运行 fmt/vet/test
make format/vet/test

# 运行 go test
make test
# 构建镜像,推送镜像,运行镜像
make docker/docker-push/docker-test

# 构建镜像
make docker

# 推送镜像
make docker-push

# 运行镜像测试
make docker-test


# 运行
# 本地测试运行
make clean && make build
copy conf/app-example.conf conf/app.conf
./PrometheusAlert
build/bin/PrometheusAlert

# 测试应用健康
curl http://localhost:8080/health
```

<br/>

=======
-------------------------------------

## 启动

```
```sh
#打开PrometheusAlert releases页面,根据需要选择需要的版本下载到本地解压并进入解压后的目录
如linux版本(https://github.com/feiyu563/PrometheusAlert/releases/download/v4.9/linux.zip)

Expand All @@ -82,6 +77,10 @@ curl http://localhost:8080/health

#启动后可使用浏览器打开以下地址查看:http://127.0.0.1:8080
#默认登录帐号和密码在app.conf中有配置

# 使用 supervisor 来守护启动。
# 配置参考 example/supervisor/prometheusalert.ini
# 如果需要将日志输出到控制台,请修改 app.conf 中 logtype=console
```

## Docker 启动
Expand Down Expand Up @@ -136,6 +135,7 @@ feiyu563/prometheus-alert:latest
- 增加告警路由和告警记录功能,可通过页面查看告警历史和操作告警消息路由。
- 增加告警语音播报插件。
- 增加支持飞书机器人应用。
- 增加告警组,可以将通知媒介写到告警组里面,便于配置和修改。

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

Expand Down Expand Up @@ -197,6 +197,7 @@ feiyu563/prometheus-alert:latest
* [告警记录-ES接入配置](doc/readme/conf-es.md)
* [语音播报](doc/readme/conf-voice.md)
* [飞书机器人应用](doc/readme/conf-feishuapp.md)
* [告警组配置](doc/readme/alertgroup.md)

* [【告警系统接入PrometheusAlert配置】](doc/readme/system.md)
* [Prometheus 接入配置](doc/readme/system-prometheus.md)
Expand Down
16 changes: 15 additions & 1 deletion conf/app-example.conf
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,18 @@ FEISHU_APPID=cli_xxxxxxxxxxxxx
# APPSECRET
FEISHU_APPSECRET=xxxxxxxxxxxxxxxxxxxxxx
# 可填飞书 用户open_id、user_id、union_ids、部门open_department_id
AT_USER_ID="xxxxxxxx"
AT_USER_ID="xxxxxxxx"


#---------------------↓告警组-----------------------
# 有其他新增的配置段,请放在告警组的上面
# 暂时仅针对 PrometheusContronller 中的 /prometheus/alert 路由
# 告警组如果放在了 wx, dd... 那部分的上分,beego section 取 url 值不太对。
# 所以这里使用 include 来包含另告警组配置

# 是否启用告警组功能
open-alertgroup=0

# 自定义的告警组既可以写在这里,也可以写在单独的文件里。
# 写在单独的告警组配置里更便于修改。
# include "alertgroup.conf"
126 changes: 113 additions & 13 deletions controllers/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type PrometheusController struct {
beego.Controller
}

// Labels are prometheus labels.
type Labels struct {
Alertname string `json:"alertname"`
Instance string `json:"instance"`
Expand All @@ -30,18 +31,23 @@ type Labels struct {
Hostgroup string `json:"hostgroup,omitempty"`
Hostname string `json:"hostname,omitempty"`
}

// Annotations are promtheus annotions.
type Annotations struct {
Description string `json:"description"`
Summary string `json:"summary"`
Mobile string `json:"mobile"` //2019年2月25日 19:09:23 增加手机号支持
Ddurl string `json:"ddurl"` //2019年3月12日 20:33:38 增加多个钉钉告警支持
Wxurl string `json:"wxurl"` //2019年3月12日 20:33:38 增加多个钉钉告警支持
Fsurl string `json:"fsurl"` //2020年4月25日 17:33:38 增加多个飞书告警支持
Email string `json:"email"` //2020年7月4日 10:15:20 增加多个email告警支持
Groupid string `json:"groupid"` //2021年2月2日 17:28:23 增加多个如流告警支持
AtSomeOne string `json:"at"` //2021年6月23日 14:02:21 增加@某人支持
Rr string `json:"rr"` //2021年9月14日 14:48:08 增加随机轮询参数支持
Mobile string `json:"mobile"` //2019年2月25日 19:09:23 增加手机号支持
Ddurl string `json:"ddurl"` //2019年3月12日 20:33:38 增加多个钉钉告警支持
Wxurl string `json:"wxurl"` //2019年3月12日 20:33:38 增加多个钉钉告警支持
Fsurl string `json:"fsurl"` //2020年4月25日 17:33:38 增加多个飞书告警支持
Email string `json:"email"` //2020年7月4日 10:15:20 增加多个email告警支持
Groupid string `json:"groupid"` //2021年2月2日 17:28:23 增加多个如流告警支持
AtSomeOne string `json:"at"` //2021年6月23日 14:02:21 增加@某人支持
Rr string `json:"rr"` //2021年9月14日 14:48:08 增加随机轮询参数支持
Alertgroup string `json:"alertgroup,omitempty"` //2023年7月 增加告警组
}

// Alerts is the alert message.
type Alerts struct {
Status string `json:"status"`
Labels Labels `json:"labels"`
Expand All @@ -50,10 +56,12 @@ type Alerts struct {
EndsAt string `json:"endsAt"`
GeneratorUrl string `json:"generatorURL"` //prometheus 告警返回地址
}

// Prometheus is the message that alertmanager sends to the receiver.
type Prometheus struct {
Status string
Alerts []Alerts
Externalurl string `json:"externalURL"` //alertmanage 返回地址
Alerts []Alerts // alerts from alertmanger is "alerts: [{},...]"
Externalurl string `json:"externalURL"` //alertmanage 返回地址
}

// 按照 Alert.Level 从大到小排序
Expand All @@ -69,14 +77,29 @@ func (a AlerMessages) Less(i, j int) bool { // 重写 Less() 方法, 从大到
return a[j].Labels.Level < a[i].Labels.Level
}

//for prometheus alert
//关于告警级别level共有5个级别,0-4,0 信息,1 警告,2 一般严重,3 严重,4 灾难
// for prometheus alert
// 关于告警级别level共有5个级别,0-4,0 信息,1 警告,2 一般严重,3 严重,4 灾难
func (c *PrometheusController) PrometheusAlert() {
alert := Prometheus{}
logsign := "[" + LogsSign() + "]"
logs.Info(logsign, string(c.Ctx.Input.RequestBody))
json.Unmarshal(c.Ctx.Input.RequestBody, &alert)
c.Data["json"] = SendMessageR(alert, "", "", "", "", "", "", logsign)

var wxurl, ddurl, fsurl, phone, email, groupid string
// check whether to open alertgroup
open := beego.AppConfig.String("open-alertgroup")
if open == "1" {
alertgroup := alert.Alerts[0].Annotations.Alertgroup
agMap := Alertgroup(alertgroup)
wxurl = agMap["wxurl"]
ddurl = agMap["ddurl"]
fsurl = agMap["fsurl"]
phone = agMap["phone"]
email = agMap["email"]
groupid = agMap["groupid"]
}

c.Data["json"] = SendMessageR(alert, wxurl, ddurl, fsurl, phone, email, groupid, logsign)
logs.Info(logsign, c.Data["json"])
c.ServeJSON()
}
Expand All @@ -97,6 +120,7 @@ func (c *PrometheusController) PrometheusRouter() {
c.ServeJSON()
}

// SendMessageR sends alert message to different media.
func SendMessageR(message Prometheus, rwxurl, rddurl, rfsurl, rphone, remail, rgroupid, logsign string) string {
//增加日志标志 方便查询日志

Expand Down Expand Up @@ -371,3 +395,79 @@ func SendMessageR(message Prometheus, rwxurl, rddurl, rfsurl, rphone, remail, rg
}
return "告警消息发送完成."
}

// Alertgroup processess alertgroup infos and generates different media url.
func Alertgroup(alertgroup string) map[string]string {
var agMap map[string]string

if len(alertgroup) == 0 {
return agMap
}

ags := strings.Split(alertgroup, ",")
// 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")
ddurl = ddurl + "," + beego.AppConfig.String(v+"::ddurl")
fsurl = fsurl + "," + beego.AppConfig.String(v+"::fsurl")
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),
"webhookurl": URLDeduplication(webhookurl),
}

return agMap
}

// url de-deplication
func URLDeduplication(url string) string {
if len(url) == 0 {
return url
}

urlSlice := strings.Split(url, ",")

uniqueMap := make(map[string]bool)
for _, s := range urlSlice {
// Remove space at the begin or end.
s = strings.TrimSpace(s)
uniqueMap[s] = true
}

uniqueSlice := []string{}
for key := range uniqueMap {
// Remove extra commas for null values
if len(key) == 0 {
continue
}
uniqueSlice = append(uniqueSlice, key)
}

sort.Strings(uniqueSlice)
newURL := strings.Join(uniqueSlice, ",")

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 ""
}

0 comments on commit f6b1dfe

Please sign in to comment.