ELK的監控工具Elastalert的報警功能擴展

Nginx請求日誌輸出到ELK,同時通過Elastalert監控ELK日誌中的關鍵信息(如http狀態500+錯誤,耗時較長的請求數達到閾值等等),這幾乎是中小型互聯網公司的標配。

Elastalert自帶的報警方式雖然多種多樣,但是不能實現根據報警信息分組發送,如研發人員也很關心這些指標,需要接受本項目的報警,運維需要接受所有項目的報警,報警方式要支持電話語音、短信、郵件、釘釘羣。要實現這些,只能自己擼腳本了。

1.首先從yaml配置文件開始

yunwei:
  member:
    zhangshan:
      phone: 15895820001
      mail: [email protected]
    lisi:
      phone: 15895820002
      mail: [email protected]
  dingtoken:
    e802cb4b5791bb08e1bc79cfd62c0a6bae4b77e8758b4b52522d5119478f1234
project1:
  member:
    zhouwu:
      phone: 15895820003
      mail: [email protected]
    wangliu:
      phone: 15895820004
      mail: [email protected]
  dingtoken:
    0a30c27cbb9bb17e5dbcb721578b7a6a490810c2fc237e1af5a1289557d31234
project2:
  member:
    liudehua:
      phone: 15895820005
      mail: [email protected]

說明:

  • yunwei代表運維組;project1\porject2代表各個研發組,研發組名稱必須與elastalert中的一級域名一致(這個跟各公司的具體情況有關,我們公司有n個平臺,每個平臺有1個或多個1級域名)
  • 每個組下的member可以有1-n個user;
  • 每個組有一個釘釘羣;
  • phone\mail\dingtoken都不是必須的,如project2沒有釘釘羣,則不發釘釘通知;
  • 對於warning級別的報警,通過phone發送短信通知,對於disaster級別的通知,通過phone發送電話語音通知,所有級別的報警都會通過mail\dingtoken發送。

2.Elastalert的規則配置

以監控500狀態爲例說明配置

es_host: 10.10.10.1
es_port: 9200
name: freq-status-500
type: frequency
index: nginx-*
num_events: 30
timeframe:
  minutes: 1
filter:
- bool:
    must:
    - terms: 
        status: ["500","501","502","503","504"]
use_terms_query: true
doc_type: doc
terms_size: 10
query_key:
- domain
- status
realert:
  minutes: 60
alert:
- command
new_style_string_format: true
command: ["/root/elastalert-0.1.38/myalert/elastalert-alarm/alarm.py","--level=warning","--domain={domain,status}","--rulename=freq-status-500","--type=frequency","--num_events=30","--timeframe=1min"]

說明:

  • 官方說可以支持多個query_key,但測試過程中發現對於frequency類型的rule,多query_key死活不成功,後來發現frequency類型下並不支持多key,需要改造(見下一章節)
  • 實現按組報警,與普通Elastalert報警的主要區別在於,command要輸出很多自定義參數,腳本通過這些參數決定發送的組合發送的內容,具體含義見alarm.py腳本
parser.add_argument('--level',dest='level',help='warning, distater')
parser.add_argument('--domain',dest='domain',help='for instance: sina_www, if rule_name start with freq-500,then sina_www-500')
parser.add_argument('--rulename', dest='rulename', help='rulename')
parser.add_argument('--type', dest='type', help='frequence, flatline')
parser.add_argument('--num_events', dest='num_events', help='num_events')
parser.add_argument('--timeframe', dest='timeframe', help='timeframe')
parser.add_argument('--reqtime_gt', dest='reqtime_gt', help='request time greater than')

3.frequency類型的規則支持多字段query_key

多query_key是非常實用的,如上文中,我要監控每個域名每種HTTP 500狀態的請求數,一個rule就能實現了。可惜作者沒支持好,需要稍微改造下。

配置舉例(use_terms_query必須配置):

use_terms_query: true
query_key:
- domain
- status

修改elastalert.py中的方法get_terms_query:

修改前:
else:
    aggs_query = query
    aggs_query['aggs'] = {'counts': {'terms': {'field': field, 'size': size}}}
return aggs_query
修改後(暫且只支持2個字段):
else:
    aggs_query = query
    field_list = field.split(",")
    if  len(field_list) == 1:
        aggs_query['aggs'] = {'counts': {'terms': {'field': field, 'size': size}}}
    elif  len(field_list) == 2:
        source= "doc['" + field_list[0] + "'].value + '-' + doc['" + field_list[1] + "'].value"
        aggs_query['aggs'] = {'counts': {'terms': {'script': {'source': source}, 'size': size}}}
    else:
        elastalert_logger.inof("Not support more than 2 fields in query_key")
return aggs_query

alert中獲取具體domain和status方式如下:

command: ["/tmp/alert_log.sh", "warning - freq 500 exceed, domain: {domain,status}"]

4.具體代碼

文件說明:

alarm.py                --程序入口,參數解析
alert_channel.py        --報警發送通道(短信、語音、郵件、釘釘羣)
alert.py                --構造發送對象和消息內容
aliyunsdk_SingleCallByTtsRequest.py   --阿里電話語音第三方庫
config-contact.yaml     --報警對象配置文件
config.py               --加載配置文件
requirements.txt        --依賴
util.py                 --工具方法

代碼地址:https://github.com/meishd/elastalert-alarm

5.效果

如域名www.sina.com的502請求數每分鐘超過30個,則報警內容如下:

注:我們ELK中將domain改成“ 一級域名_二級域名 ”的格式入庫

warning: sina_www status of 502 exceed 30 per 1min

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章