这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
May 13 10:04:40 deskmini alertmanager[767]: ts=2023-05-13T02:04:40.869Z caller=notify.go:732 level=warn component=dispatcher receiver=web.hook integration=webhook[0] msg="Notify attempt failed, will retry later" attempts=1 err="Post \"http://192.168.50.134:8888/webhook\": dial tcp http://192.168.50.134:8888/webhook: connect: connection refused"
May 13 10:09:40 deskmini alertmanager[767]: ts=2023-05-13T02:09:40.869Z caller=dispatch.go:352 level=error component=dispatcher msg="Notify for alerts failed" num_alerts=1 err="web.hook/webhook[0]: notify retry canceled after 16 attempts: Post \"http://192.168.50.134:8888/webhook\": dial tcp http://192.168.50.134:8888/webhook: connect: connection refused"
May 13 10:09:40 deskmini alertmanager[767]: ts=2023-05-13T02:09:40.869Z caller=notify.go:732 level=warn component=dispatcher receiver=web.hook integration=webhook[0] msg="Notify attempt failed, will retry later" attempts=1 err="Post \"http://192.168.50.134:8888/webhook\": dial tcp http://192.168.50.134:8888/webhook: connect: connection refused"
名称 | 链接 | 备注 |
---|---|---|
项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
go install github.com/cloudwego/hertz/cmd/hz@latest
hz new -module webhook
go mod tidy
tree webhook
webhook
├── biz
│ ├── handler
│ │ └── ping.go
│ └── router
│ └── register.go
├── build.sh
├── go.mod
├── main.go
├── router_gen.go
├── router.go
└── script
└── bootstrap.sh
package model
import "time"
type Alert struct {
Labels map[string]string `json:"labels"`
Annotations map[string]string `json:annotations`
StartsAt time.Time `json:"startsAt"`
EndsAt time.Time `json:"endsAt"`
}
type Notification struct {
Version string `json:"version"`
GroupKey string `json:"groupKey"`
Status string `json:"status"`
Receiver string `json:receiver`
GroupLabels map[string]string `json:groupLabels`
CommonLabels map[string]string `json:commonLabels`
CommonAnnotations map[string]string `json:commonAnnotations`
ExternalURL string `json:externalURL`
Alerts []Alert `json:alerts`
}
package model
// 飞书机器人支持的POST数据结构
// 请求体相关
type LarkRequest struct {
MsgType string `json:"msg_type"`
Content Content `json:"content"`
}
type Content struct {
Text string `json:"text"`
}
// 响应体相关
type LarkResponse struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data Data `json:"data"`
}
type Data struct {
}
package util
import (
"bytes"
"fmt"
"webhook/biz/model"
)
// TransformToLarkRequest 根据alertmanager的对象,创建出飞书消息的对象
func TransformToLarkRequest(notification model.Notification) (larkRequest *model.LarkRequest, err error) {
var buffer bytes.Buffer
// 先拿到分组情况
buffer.WriteString(fmt.Sprintf("通知组%s,状态[%s]\n告警项\n\n", notification.GroupKey, notification.Status))
// 每条告警逐个获取,拼接到一起
for _, alert := range notification.Alerts {
buffer.WriteString(fmt.Sprintf("摘要:%s\n详情:%s\n", alert.Annotations["summary"], alert.Annotations["description"]))
buffer.WriteString(fmt.Sprintf("开始时间: %s\n\n", alert.StartsAt.Format("15:04:05")))
}
// 构造出飞书机器人所需的数据结构
larkRequest = &model.LarkRequest{
MsgType: "text",
Content: model.Content{
Text: buffer.String(),
},
}
return larkRequest, nil
}
// Code generated by hertz generator.
package handler
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"webhook/biz/model"
"webhook/biz/util"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/hlog"
"github.com/cloudwego/hertz/pkg/common/utils"
"github.com/cloudwego/hertz/pkg/protocol/consts"
)
const (
// 请使用您自己的机器人的webhook地址
LARK_URL = "https://open.feishu.cn/open-apis/bot/v2/hook/12345678-1234-1234-1234-123456789012"
)
// Ping .
func AlertmanagerWebhook(ctx context.Context, c *app.RequestContext) {
var notification model.Notification
// 绑定对象
err := c.BindAndValidate(¬ification)
if err != nil {
c.JSON(consts.StatusBadRequest, utils.H{
"error": err.Error(),
})
return
}
hlog.Info("收到alertmanager告警:\n%s", notification)
// 根据alertmanager的请求构造飞书消息的请求数据结构
larkRequest, _ := util.TransformToLarkRequest(notification)
// 向飞书服务器发送POST请求,将飞书服务器返回的内容转为对象
bytesData, _ := json.Marshal(larkRequest)
req, _ := http.NewRequest("POST", LARK_URL, bytes.NewReader(bytesData))
req.Header.Add("content-type", "application/json")
res, err := http.DefaultClient.Do(req)
// 飞书服务器可能通信失败
if err != nil {
hlog.Error("请求飞书服务器失败:%s", err)
c.JSON(consts.StatusInternalServerError, utils.H{
"error": err.Error(),
})
return
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
var larkResponse model.LarkResponse
err = json.Unmarshal([]byte(body), &larkResponse)
// 飞书服务器返回的包可能有问题
if err != nil {
hlog.Error("获取飞书服务器响应失败:%s", err)
c.JSON(consts.StatusInternalServerError, utils.H{
"error": err.Error(),
})
return
}
hlog.Info("向飞书服务器发送消息成功")
c.JSON(consts.StatusOK, utils.H{
"message": "successful receive alert notification message!",
})
}
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Package",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}"
}
]
}
#!/bin/bash
CURDIR=$(cd $(dirname $0); pwd)
BinaryName=
echo "$CURDIR/bin/${BinaryName}"
exec $CURDIR/bin/${BinaryName}
#!/bin/bash
CURDIR=$(cd $(dirname $0); pwd)
BinaryName=webhook
echo "$CURDIR/bin/${BinaryName}"
exec $CURDIR/bin/${BinaryName}