promethesu告警规则配置,alertmanager通过webhook通知

news/2024/5/19 1:19:40 标签: prometheus

文章目录

  • 前言
  • 一、promethesu告警
  • 二、告警配置
  • 三、告警通知
    • prometheus 配置 alertmanager
    • alertmanager 配置 webhook通知
    • 编写接口接收 webhook
  • 总结


前言

如果没有学习过prometheus的基础和监控的同学,可以先过一遍这篇文章
https://blog.csdn.net/weixin_42132143/article/details/134772543?spm=1001.2014.3001.5501


一、promethesu告警

Prometheus 收集和存储监控数据,然后根据自定义的告警规则进行数据分析,从而触发报警。配置告警规则通常包括以下几个步骤:

  1. 定义告警规则:告警规则是在 Prometheus 的配置文件中定义的,通常位于 prometheus.yml 文件中的 rules 部分。你需要创建一个告警规则文件(例如 alert.rules.yml),在这个文件中定义你的告警逻辑。

  2. 配置告警规则文件:在 prometheus.yml 中指定告警规则文件的位置,例如:

    rule_files:
      - "alert.rules.yml"
    
  3. 编写告警规则:在告警规则文件中编写具体的规则。每条规则包括以下几个部分:

  • alert: 告警名称。

  • expr: 告警表达式,当表达式的结果为 true 时触发告警。

  • for: 等待一段时间后才触发告警,用于防止短暂的数据波动导致的误报。

  • labels: 附加到告警上的标签,可以用来分类告警。

  • annotations: 告警的详细说明,如描述、摘要等。

    例如:

    groups:
    - name: example
      rules:
      - alert: HighRequestLatency
        expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
        for: 10m
        labels:
          severity: page
        annotations:
          summary: High request latency
    
    
  1. 配置报警通知:Prometheus 本身只是产生告警不直接发送告警,是通过 Alertmanager 来管理告警通知。你需要配置 Alertmanager 的配置文件 alertmanager.yml 来定义通知的接收者和方式,如webhook、邮件、Slack、PagerDuty 等。

二、告警配置

编写rule文件

我们自定义一个告警规则,这里针对 node_exporter 的内存使用率,超过80%触发告警:

新建一个 rule 文件,

vi /etc/prometheus/rules/node_rule.yml
groups:
- name: node
  rules:
  - alert: MemoryCritical
    expr: 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90
    for: 5m
    labels:
      severity: warning
      object: "{{ $labels.instance }}"
      content: 内存使用率高于90%
      job: "{{ $labels.job }}"
    annotations:
      summary: "Low memory available (instance {{ $labels.instance }})"
      description: "Memory usage rate above 90% for more than 5 minute"

如果是想新增一些自定义的标签,可以放在 groups.rules.labels 下面,上面的 object、content、job 就是我新增的自定义标签

prometheus_90">prometheus配置

修改 prometheus 的配置文件

rule_files:
  - "/etc/prometheus/rules/node_rule.yml"

重启 prometheus 服务,使之生效

prometheus_102">prometheus产生告警

已经配置好告警规则了,这时候我们给安装 node_exporter 的被监控节点加压,使之内存使用率高于 80%

然后 prometheus 就会产生告警信息,可以在 prometheus 的页面看到产生的告警信息

http://localhost:9090/alerts

这个页面会看到诸如此类的告警规则,变成红色就是产生了告警

在这里插入图片描述

三、告警通知

prometheus__alertmanager_116">prometheus 配置 alertmanager

prometheus 已经产生了告警了,我们需要将告警信息推送给 alertmanager

这里就不放 alertmanager 的安装教程了

修改 prometheus 的配置文件,配置上 alertmanager

alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - 192.168.231.56:9093

重启 prometheus

这时候你就可以在 alertmanager 页面看到接收到的告警信息

prometheus 每次都会把当前所有已经产生的告警信息推送过去 alertmanager

在这里插入图片描述

alertmanager 配置 webhook通知

这时候只是 alertmanager 接收到了告警信息,而 alertmanager 它本身就是一个用于配置告警通知的工具

我们这里使用 webhook 的方式来通知

修改 alertmanager 的配置文件

global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'content', 'object']
  group_wait: 10s
  group_interval: 10s
  repeat_interval: 24h
  receiver: 'web.hook'
receivers:
- name: 'web.hook'
  webhook_configs:
  - url: 'http://172.16.205.66:8122/notify/alert/send'

说明:

  1. 上面的配置中 group by 指定了多个字段,作用是根据这几个字段来区分同一条告警,防止重复告警。上面也说了 prometheus 每次都会把当前所有已经产生的告警信息推送过去 alertmanager,如果 group by 不做区分,或者只用了默认的 alertname 一个字段,很有可能会导致在多个告警触发的场景下,导致之前已经告警过的信息再次告警通知。
  2. 上面的配置中的 receiver 指定是 web.hook 方式推送,然后在 receivers 配置其地址。webhook方式其实说白了,他就是 由 alertmanager 往这个指定的地址,发送一个 POST 方式的 HTTP 请求而已,所以我们的接收端只需要编写一个普通的 web 项目,里面有一个 POST 接口,接口的地址对应上就可以了。

编写接口接收 webhook

直接新建一个空白的 springboot 项目,加上一个接口,接收来自 alertmanager 的推送,然后根据自己的业务处理就行了,下面放一点核心的代码:

@PostMapping("/send")
public R send(HttpServletRequest httpServletRequest) throws IOException {
	CachedBodyHttpServletRequest request = new CachedBodyHttpServletRequest(httpServletRequest);

	// alertmanager的webhook通知会有短时间内的超时重传,这里用异步
	alertNotifyService.notify(request);

	return R.success();
}
public class CachedBodyHttpServletRequest extends HttpServletRequestWrapper {
    private final String cachedBody;

    public CachedBodyHttpServletRequest(HttpServletRequest request) throws IOException {
        super(request);
        StringBuilder body = new StringBuilder();
        try (BufferedReader bufferedReader = request.getReader()) {
            char[] charBuffer = new char[128];
            int bytesRead = -1;
            while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                body.append(charBuffer, 0, bytesRead);
            }
        }
        this.cachedBody = body.toString();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new StringReader(this.cachedBody));
    }
}
@Async
public void notify(HttpServletRequest request) {
	// 解析prometheus请求参数
	AlertManagerBean msg = getRequestReaderMsg(request);
	System.out.println(msg);
	if(msg == null)
		return;

	// 通知发送逻辑

}

private AlertManagerBean getRequestReaderMsg(HttpServletRequest request){
	AlertManagerBean alertManagerBean = null;
	try (BufferedReader reader = request.getReader()) {
		// 获取JSON请求参数
		String jsonBody = reader.lines().reduce("", (accumulator, actual) -> accumulator + actual);
		// log.info(jsonBody);
		alertManagerBean = JSONUtil.toBean(jsonBody, AlertManagerBean.class);
	} catch (Exception e) {
		e.printStackTrace();
		log.warn("解析prometheus请求参数失败");
	}
	return alertManagerBean;
}
@Data
public class AlertManagerBean {

    private String status;
    private List<AlertManagerAlert> alerts;

}
@Data
public class AlertManagerAlert {

    private String status;
    private AlertManagerLabel labels;
    private AlertManagerAnnotation annotations;

}
@Data
public class AlertManagerLabel {

    private String alertname;
    private String instance;
    private String device;
    private String mountpoint;
    private String fstype;

    private String level;
    private String job;
    private String content;
    private String object;

}
@Data
public class AlertManagerAnnotation {

    private String summary;
    private String description;

}

总结

欢迎指出我的错误!


http://www.niftyadmin.cn/n/5248542.html

相关文章

GUN编译器(gcc/g++)- 编译过程

说明 gcc test.c -o test g test.cpp -o test如上&#xff0c;可以很简单的使用一条命令将源码编译成可执行文件&#xff0c;但是实际上编译过程是一个比较复杂的工作&#xff0c;gcc/g只是编译系统的入口程序&#xff0c;解析用户输入的参数&#xff0c;顺序调用预处理器&…

Python基础——两个常用且容易忘记的知识点

1. replace函数的第三个参数 replace 方法提供了一个可选的参数 count&#xff0c;可以用于指定替换的次数。你可以将 count 设置为 1 来限制替换的次数&#xff0c;只替换第一个匹配项。 下面是使用 replace 方法限制替换次数的示例&#xff1a; date_str "2023/05/1…

【2023.12.4练习】数据库知识点复习测试

概论 数据表&#xff1a;用于存储现实中数据的联系。 储存信息联系。 字段&#xff1a;又称列&#xff0c;如姓名、年龄、编号等。 记录&#xff1a;又称元组&#xff0c;为数据表中的一行&#xff0c;代表了一个实体的信息。 数据库&#xff08;DB&#xff09;&#xff1…

既然UDP更快,为啥这么多年一直用TCP ?

你们好啊&#xff0c;我是老杨。 有点基本技术常识的粉丝朋友都知道&#xff0c;UDP肯定是比TCP快的。 很多人对TCP和UDP的了解很浅&#xff0c;直到自己真的经历了一些通信项目之后&#xff0c;你才会愿意根据实际情况埋头苦学&#xff0c;企图“速成”一下。 要是问你为什…

红队攻防实战之Redis-RCE集锦

心若有所向往&#xff0c;何惧道阻且长 Redis写入SSH公钥实现RCE 之前进行端口扫描时发现该机器开着6379&#xff0c;尝试Redis弱口令或未授权访问 尝试进行连接Redis&#xff0c;连接成功&#xff0c;存在未授权访问 尝试写入SSH公钥 设置redis的备份路径 设置保存文件名 …

Java中不同转换符实现不同数据类型到字符串的转换

String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的同学应该记得C语言的sprintf()方法&#xff0c;两者有类似之处。format()方法有两种重载形式。 format(String format, Object... args) 新字符串使用本地语言环境&#xff0c;制定字符串格式…

spring boot整合mybatis进行部门管理管理的增删改查

部门列表查询&#xff1a; 功能实现&#xff1a; 需求&#xff1a;查询数据库表中的所有部门数据&#xff0c;展示在页面上。 准备工作&#xff1a; 准备数据库表dept&#xff08;部门表&#xff09;&#xff0c;实体类Dept。在项目中引入mybatis的起步依赖&#xff0c;mysql的…

支付宝小程序接口传参会默认排序

一&#xff1a;问题 描述&#xff1a;最近项目中的接口都加了签名&#xff0c;在同步到支付宝小程序上时&#xff0c;发现有些接口报错&#xff0c;经过排查&#xff0c;导致报错的原因是因为传参顺序被支付宝小程序默认排序了&#xff0c;比如&#xff1a; 设置的原始参数&a…