alertmanager告警存储方案

该文章描述了一个用Go编写的webhook程序,接收Alertmanager的告警信息,然后过滤并存储到Elasticsearch中以进行历史告警分析,旨在提升系统稳定性的诊断能力。程序使用Gin框架处理HTTP请求,解析JSON数据,并将告警事件转化为Elasticsearch文档进行索引。

背景:由于alertmanager没有历史告警存储功能。在工作中我们可能需要 收集历史告警信息进行数据分析,找到系统的瓶颈,从而提高稳定性

实现方法:go语言写一个 针对alertmanager的webhook 程序。收集告警信息进行过滤然后存入es中

具体代码如下


import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"github.com/elastic/go-elasticsearch/v8"
	"github.com/elastic/go-elasticsearch/v8/esapi"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"reflect"
	"time"
)

type Alert struct {
	Status      string      `json:"status"`
	Labels      Labels      `json:"labels"`
	Annotations Annotations `json:"annotations"`
	StartsAt    string      `json:"startsAt"`
	EndsAt      string      `json:"endsAt"`
	//GeneratorURL string      `json:"generatorURL"`
	//Fingerprint  string      `json:"fingerprint"`
}

type Labels struct {
	AlertName string `json:"alertname"`
	Group     string `json:"group"`
	Instance  string `json:"instance"`
	Job       string `json:"job"`
	Severity  string `json:"severity"`
	Team      string `json:"team"`
}

type Annotations struct {
	Description string `json:"description"`
	//Summary     string `json:"summary"`
	//Value       string `json:"value"`
}

type AlertDetail struct {
	AlertName   string
	Group       string
	Severity    string
	Team        string
	Description string
	Time        float64
}

func HandleJSON(c *gin.Context) {
	var data struct {
		//Receiver          string      `json:"receiver"`
		Status string  `json:"status"`
		Alerts []Alert `json:"alerts"`
		//GroupLabels       Labels      `json:"groupLabels"`
		//CommonLabels      Labels      `json:"commonLabels"`
		//CommonAnnotations Annotations `json:"commonAnnotations"`
		//TruncatedAlerts   int         `json:"truncatedAlerts"`
	}

	if err := c.ShouldBindJSON(&data); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	//fmt.Println(data)

	if data.Status != "resolved" {
		c.JSON(http.StatusOK, gin.H{"message": "JSON data received and processed"})
		return
	}

	//配置es
	cfg := elasticsearch.Config{
		Addresses: []string{"http://127.0.0.1:9200"}, // 连接地址,根据自己的实际情况修改
	}

	// 创建 Elasticsearch 客户端
	client, err := elasticsearch.NewClient(cfg)
	if err != nil {
		fmt.Println("Error creating the client: ", err)
		return
	}

	for _, a := range data.Alerts {
		startsAt, _ := time.Parse(time.RFC3339, a.StartsAt)
		endsAt, _ := time.Parse(time.RFC3339, a.EndsAt)
		duration := endsAt.Sub(startsAt)
		durationInHours := duration.Hours()
		alertdetail := AlertDetail{
			AlertName:   a.Labels.AlertName,
			Group:       a.Labels.Group,
			Team:        a.Labels.Team,
			Description: a.Annotations.Description,
			Time:        durationInHours,
		}
		fmt.Println(alertdetail)
		// 将文档结构体转换为 JSON 字符串
		jsonStr, err := json.Marshal(alertdetail)
		if err != nil {
			fmt.Println("Error marshaling document: ", err)
			return
		}

		// 创建索引请求
		req := esapi.IndexRequest{
			Index: "alert",
			Body:  bytes.NewReader(jsonStr),
		}

		// 执行索引请求
		res, err := req.Do(context.Background(), client)
		if err != nil {
			fmt.Println("Error executing the request: ", err)
			return
		}
		defer res.Body.Close()

		// 检查响应状态码
		if res.IsError() {
			fmt.Printf("Error indexing document: %s", res.Status())
		} else {
			fmt.Println("Document indexed successfully")
		}

	}

	c.JSON(http.StatusOK, gin.H{"message": "JSON data received and processed"})
}

func SearchES(c *gin.Context) {
	//配置es
	cfg := elasticsearch.Config{
		Addresses: []string{"http://127.0.0.1:9200"}, // 连接地址,根据自己的实际情况修改
	}

	// 创建 Elasticsearch 客户端
	client, err := elasticsearch.NewClient(cfg)
	if err != nil {
		fmt.Println("Error creating the client: ", err)
		return
	}
	//获取es数据
	// 构造查询请求
	req := esapi.SearchRequest{
		Index: []string{"alert"}, // 索引名称
	}

	res, err := req.Do(context.Background(), client)
	if err != nil {
		log.Fatalf("Error executing search request: %s", err)
	}
	defer res.Body.Close()

	// 处理响应结果
	if res.IsError() {
		log.Fatalf("Search request returned error code %d", res.StatusCode)
	}
	respjson := res.String()
	fmt.Println(respjson)
	fmt.Println(reflect.TypeOf(respjson))
	c.JSON(http.StatusOK, respjson)

}

func main() {
	router := gin.Default()

	router.POST("/receive", HandleJSON)
	router.GET("/search", SearchES)

	// 启动服务器
	router.Run(":8080")
}
<think>首先,用户的问题是关于配置AlertManager以通过企业微信发送告警通知。我需要基于系统级指令来构建我的回答。 系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠。 用户的问题:"我想配置AlertManager以通过企业微信发送告警通知 请问AlertManager 配置企业微信告警通知指南" 参考的引用: - [^1]: 关于AlertManager基础配置和安装启动。 - [^2]: 关于Prometheus接入AlertManager配置企业微信告警,基于K8S环境部署,包括企业微信告警发送过程。 - [^3]: 关于Prometheus生态组件,包括AlertManager处理告警并发送通知。 这些引用提供了一些背景信息,但用户的具体需求是配置AlertManager通过企业微信发送告警通知。所以,我需要基于这些信息构建一个指南。 回答结构: - 结构清晰,逐步解决问题。 - 使用中文。 - 可能包括代码或配置示例。 - 最后生成相关问题。 由于用户的问题涉及配置指南,我应该包括步骤: 1. 安装和启动AlertManager(基于[^1])。 2. 配置AlertManager以支持企业微信告警(基于[^2])。 3. 测试和验证配置。 在回答中,我需要自然地引用引用段落。例如,当提到基础配置时,引用[^1];当提到企业微信配置时,引用[^2]。 数学表达式:用户的问题是关于IT配置,可能不涉及数学表达式。但如果有任何数学相关的内容,比如在性能分析中,我需要使用LaTeX格式。但在这个上下文中,可能不需要。 生成相关问题:在回答结束时,生成2-3个相关问题,类似于示例。 完整回答结构: 1. 引言:简要介绍配置AlertManager通过企业微信发送告警的重要性。 2. 步骤指南: - 步骤1: 安装和启动AlertManager(引用[^1])。 - 步骤2: 配置AlertManager以使用企业微信接收器(receiver)。 - 步骤3: 配置企业微信Webhook。 - 步骤4: 测试配置。 3. 总结。 4. 生成相关问题。 基于引用[^2],它提到在K8S环境部署,并配置企业微信告警。所以,我可以包括具体配置示例。 引用[^2]说:"Prometheus接入AlterManager配置企业微信告警(基于K8S环境部署)",并描述了过程。所以,我会使用那个作为参考。 确保回答真实可靠:基于提供的引用,我可以构建指南。如果我有额外知识,我可以添加,但要基于引用。 最后,添加相关问题,如: 1. 如何优化AlertManager告警分组? 2. AlertManager与其他告警系统的集成? 3. 常见问题排查。 现在,构建回答。</think>### AlertManager配置企业微信告警通知指南 配置AlertManager通过企业微信发送告警通知,是现代IT监控体系中的关键步骤,能有效提升告警响应效率。本指南基于Kubernetes(K8S)环境部署(这是常见场景),提供逐步配置方案。整个过程包括安装AlertManager、配置企业微信接收器、测试告警发送等步骤。以下步骤基于Prometheus生态最佳实践,确保可靠性和可扩展性[^2]。 #### 步骤1: 安装和启动AlertManager 首先,确保AlertManager已正确安装和运行。AlertManagerPrometheus生态中负责告警管理的组件,需要与Prometheus集成。以下是基于K8S环境的基本安装步骤: 1. 使用Helm或YAML文件部署AlertManager。例如,创建一个Helm Chart: ```yaml # alertmanager-values.yaml config: global: resolve_timeout: 5m route: group_by: ['alertname'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'wechat' receivers: - name: 'wechat' wechat_configs: - corp_id: 'YOUR_CORP_ID' agent_id: 'YOUR_AGENT_ID' secret: 'YOUR_SECRET' to_user: '@all' ``` 部署命令: ```bash helm install alertmanager prometheus-community/kube-prometheus-stack -f alertmanager-values.yaml ``` 这将启动AlertManager服务。安装完成后,可通过浏览器访问`http://<AlertManager-IP>:9093`验证服务状态[^1]。 #### 步骤2: 配置企业微信接收器 AlertManager通过`receivers`配置定义告警接收方式。企业微信需要Webhook集成,您需先在企业微信后台创建应用并获取凭据: 1. 登录企业微信管理后台,创建新应用(如“Prometheus告警”),记录`Corp ID`、`Agent ID`和`Secret`。 2. 更新AlertManager配置文件(通常是`alertmanager.yml`),添加企业微信接收器: ```yaml receivers: - name: 'wechat_alert' wechat_configs: - send_resolved: true # 发送告警恢复通知 corp_id: 'your_corp_id' # 替换为您的Corp ID agent_id: 'your_agent_id' # 替换为您的Agent ID secret: 'your_secret' # 替换为您的Secret to_user: '@all' # 发送给所有用户,或指定用户ID message: '{{ template "wechat.message" . }}' # 使用模板格式化消息 templates: - '/etc/alertmanager/templates/*.tmpl' # 模板文件路径 ``` 其中,`wechat.message`模板用于自定义告警内容。创建一个模板文件`wechat.tmpl`: ```text {{ define "wechat.message" }} **告警名称**: {{ .CommonLabels.alertname }} **级别**: {{ .CommonLabels.severity }} **详情**: {{ .CommonAnnotations.description }} **触发时间**: {{ .StartsAt }} {{ end }} ``` 此配置确保告警信息被分组后发送(等待`group_wait`时间后发送到企业微信),避免信息过载[^2]。 #### 步骤3: 集成Prometheus并测试告警 AlertManager需与Prometheus联动。配置Prometheus的`prometheus.yml`文件指向AlertManager: ```yaml alerting: alertmanagers: - static_configs: - targets: ['alertmanager:9093'] # AlertManager服务地址 rule_files: - /etc/prometheus/rules/*.rules # 告警规则文件 ``` 创建一条测试告警规则(如`test_alert.rules`): ```yaml groups: - name: test-alerts rules: - alert: HighCPUUsage expr: avg(rate(container_cpu_usage_seconds_total[5m])) > 0.8 # CPU使用率超过80%时触发 for: 5m labels: severity: critical annotations: description: "CPU使用率过高,请检查容器资源。" ``` 部署后,模拟告警(如通过压力测试)。企业微信将收到类似消息: ``` **告警名称**: HighCPUUsage **级别**: critical **详情**: CPU使用率过高,请检查容器资源。 **触发时间**: 2023-10-01T10:00:00Z ``` 如果一切正常,告警会在`group_wait`时间后发送,确保高效通知[^2]。 #### 常见问题与优化 - **问题排查**:如果告警未发送,检查AlertManager日志(`kubectl logs <alertmanager-pod>`),确认企业微信凭据正确。 - **性能优化**:调整`group_wait`和`group_interval`参数,减少告警风暴。例如,设置`group_wait: 10s`可加快低优先级告警响应。 - **安全性**:使用K8S Secrets存储企业微信凭据,避免硬编码风险。 通过以上步骤,AlertManager可稳定发送告警到企业微信,提升监控系统的智能化水平[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值