基於elasticsearch的自定義業務告警的設計思路
- 2019 年 10 月 5 日
- 筆記
A系統與B系統之間有很多介面交互,但是有一段時間介面經常報錯,作為開發如果不能第一時間知道問題且及時解決的話就會收到業務投訴,當月績效涼涼。
如果你也有這種場景,那麼你就需要一個及時告警的功能。
實現方案
實現及時告警分以下兩種場景:
- 有ELK日誌收集
- 沒有ELK日誌收集
沒有ELK日誌收集的方案
~~很簡單,搭建一個日誌收集環境(O(∩_∩)O哈哈~)~~
需要在業務程式碼中嵌入硬編碼,每次catch到異常直接發送告警資訊告警平台進行告警
有ELK日誌收集的方案
最核心的是 elasticsearch組件,所有的告警方案前提條件都是告警日誌需要進ES,然後定時從ES中檢索出符合業務規定的告警日誌(比如ERROR日誌),如果檢索出來的告警日誌滿足一定條件就觸發告警通知。
實現方式主要有以下幾種:
-
ES WATCHER
這個是elasticsearch的官方插件,它可以根據數據的變化提供警報和通知,目前是收費的,具體操作配置可以參看官方地址 -
elastalert
是Yelp公司基於python寫的告警框架,大家可以去GitHub上查看具體使用方法。elastalert -
自定義開發
自定義開發實現
主要由以下幾個步驟實現:
- 分離出單獨的告警日誌,與業務日誌分離
- 在logstash中解析日誌,構建格式化的告警日誌,需要有以下幾個關鍵參數:
日誌級別、日誌時間、日誌描述、開發模組、關聯主鍵、請求參數、響應參數 - 定時任務每隔一段時間去ES中檢索符合要求的日誌,如果檢索到就發送告警通知。
核心程式碼
- 日誌格式化
我們直接在客戶端構建好格式化的日誌,以json的形式輸出到日誌文件中,這樣在logstash解析的時候直接使用json解析即可。
這一步不是必須的,可以自由構建日誌格式,然後在logstash解析的時候使用grok語法進行解析。
public class AlarmLog { /**日誌級別*/ private String logLevel; /**日誌描述*/ private String message; /**關聯主鍵 一般使用requestId*/ private String refCode; /**請求參數*/ private String parm; /**響應數據*/ private String response; /**開發模組,根據此參數配置模組負責人*/ private String module; /**日誌時間*/ private long logTime; ... }
- 關鍵查詢
在單獨的定時器項目中使用如下查詢語法就可以檢索出具體的告警日誌。檢索出來就可以根據日誌中的模組欄位找出具體的模組負責人,然後發送告警通知給負責人。
public List<LogDoc> findRangeLogByLevel(DateTime minRange, DateTime maxRange, String logLevel) { //需要強制轉換成小寫 logLevel = logLevel.toLowerCase(); SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(boolQuery() //module 必須有值才能告警 .must(existsQuery("module")) .must(termQuery("logLevel", logLevel)) .must(rangeQuery("logTime") .from(minRange.getMillis()) .to(maxRange.getMillis()))) .build(); return elasticsearchTemplate.queryForList(searchQuery, LogDoc.class); }