文章目錄
- 前言
- 一、promethesu告警
- 二、告警配置
- 編寫rule文件
- prometheus配置
- prometheus產生告警
- 三、告警通知
- prometheus 配置 alertmanager
- alertmanager 配置 webhook通知
- 編寫接口接收 webhook
- 總結
前言
如果沒有學習過prometheus的基礎和監控的同學,可以先過一遍這篇文章
https://blog.csdn.net/weixin_42132143/article/details/134772543?spm=1001.2014.3001.5501
一、promethesu告警
Prometheus 收集和存儲監控數據,然后根據自定義的告警規則進行數據分析,從而觸發報警。配置告警規則通常包括以下幾個步驟:
-
定義告警規則:告警規則是在 Prometheus 的配置文件中定義的,通常位于 prometheus.yml 文件中的 rules 部分。你需要創建一個告警規則文件(例如 alert.rules.yml),在這個文件中定義你的告警邏輯。
-
配置告警規則文件:在 prometheus.yml 中指定告警規則文件的位置,例如:
rule_files:- "alert.rules.yml"
-
編寫告警規則:在告警規則文件中編寫具體的規則。每條規則包括以下幾個部分:
-
alert: 告警名稱。
-
expr: 告警表達式,當表達式的結果為 true 時觸發告警。
-
for: 等待一段時間后才觸發告警,用于防止短暫的數據波動導致的誤報。
-
labels: 附加到告警上的標簽,可以用來分類告警。
-
annotations: 告警的詳細說明,如描述、摘要等。
例如:
groups: - name: examplerules:- alert: HighRequestLatencyexpr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5for: 10mlabels:severity: pageannotations:summary: High request latency
- 配置報警通知:Prometheus 本身只是產生告警不直接發送告警,是通過 Alertmanager 來管理告警通知。你需要配置 Alertmanager 的配置文件 alertmanager.yml 來定義通知的接收者和方式,如webhook、郵件、Slack、PagerDuty 等。
二、告警配置
編寫rule文件
我們自定義一個告警規則,這里針對 node_exporter 的內存使用率,超過80%觸發告警:
新建一個 rule 文件,
vi /etc/prometheus/rules/node_rule.yml
groups:
- name: noderules:- alert: MemoryCriticalexpr: 100 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100 > 90for: 5mlabels:severity: warningobject: "{{ $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配置
修改 prometheus 的配置文件
rule_files:- "/etc/prometheus/rules/node_rule.yml"
重啟 prometheus 服務,使之生效
prometheus產生告警
已經配置好告警規則了,這時候我們給安裝 node_exporter 的被監控節點加壓,使之內存使用率高于 80%
然后 prometheus 就會產生告警信息,可以在 prometheus 的頁面看到產生的告警信息
http://localhost:9090/alerts
這個頁面會看到諸如此類的告警規則,變成紅色就是產生了告警
三、告警通知
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: 5mroute:group_by: ['alertname', 'content', 'object']group_wait: 10sgroup_interval: 10srepeat_interval: 24hreceiver: 'web.hook'
receivers:
- name: 'web.hook'webhook_configs:- url: 'http://172.16.205.66:8122/notify/alert/send'
說明:
- 上面的配置中 group by 指定了多個字段,作用是根據這幾個字段來區分同一條告警,防止重復告警。上面也說了 prometheus 每次都會把當前所有已經產生的告警信息推送過去 alertmanager,如果 group by 不做區分,或者只用了默認的 alertname 一個字段,很有可能會導致在多個告警觸發的場景下,導致之前已經告警過的信息再次告警通知。
- 上面的配置中的 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();}@Overridepublic 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;}
總結
歡迎指出我的錯誤!