Alertmanager配置webhook


--時間:2020年7月22日

--作者:飛翔的小胖豬

說明

在prometheus監控中時常會用到alertmanager軟件進行告警信息發送,常見的可以使用郵件或對接企業微信等應用實現提示信息的推送。在某些特殊情況下alertmanager無法對接生產環境中的已存在的api,需要自定一個中間層連接alertmanager和用戶的應用實現特定數據的推送。

文檔通過使用alertmanager軟件的webhook功能把信息推送到python編寫的api中,然后把接收到的數據進行清理篩選出有用的數據,按照其他api的數據格式重新整理數據格式並推送給指定的api。

環境准備

提前安裝配置好prometheus+alertmanager+consul+node_exporter環境。

准備一台安裝有python3的服務器

配置詳情

alertmanager配置

配置alertmanager軟件配置參數。

# vim alertmanager.yml

global:
  resolve_timeout: 5m

route:
  group_by: ['instance']
  group_wait: 10s
  group_interval: 20s
  repeat_interval: 20s
  #repeat_interval: 1h
  receiver: 'webhook'
receivers:
- name: 'webhook'
  webhook_configs:
  - url: 'http://192.168.111.1:5000/send'

 參數說明:

    group_by:告警組名

    group_wait:當收到告警的時候,等待10秒確認時間內是否有新告警,如有則一並發送

    group_interval:發送前等待時間,配置中設置接收到告警后再等待20秒發送

    repeat_interval:重復告警周期時間,由於是測試所以設置比較短,在生產環境中一般設置為1h

    receiver:指示信息推送給誰,此處設置的值必須在receivers中能夠找到

    webhook_configs:調用api的url地址,實驗環境使用192.168.111.1創建的一個api。

 

python腳本

 app1.py:192.168.111.1主機上的python腳本

# -*- coding:utf-8 -*-
from flask import Flask, request
import requests
import json
app1 = Flask(__name__)
'''
腳本功能:從alertmanager獲取到json文件,然后格式化過后再調用其他api進行處理。
'''
@app1.route('/send', methods=['POST'])
def send():
 try:
  url_test_api = 'http://192.168.111.83:5000/send'   #假定這個url為另一個應用的api
  dict1 = dict()   #定義一個字典用來存放清理過后的數據,最后需要把這個數據推送給其他應用
  data = json.loads(request.data)   #轉換從alertmanager獲得的json數據為dict類型
  alerts = data['alerts']           #獲取key為alerts的數據賦值給變量alerts
  dict1['type'] = '監控'            #手動在dict1中加入key為type值為'監控'
  for i in alerts:
   info = i.get('labels')     #i是一個dict類型數據,獲取key為labels的數據
   #以下內容就是把alertmanager中提取的數據加入到我們自定義的字典中。
   #把數據以dict的方式加入到dict1的fname key中。 info.get('instance').split(':')[0]表示以:分割截取第一段字符串,源字符192.168.111.12:9100  截取后 192.168.111.12,
   dict1['fname'] = { '提示類型':i.get('status'),'告警信息':info.get('alertname'),"告警節點":info.get('instance').split(':')[0]}
   j = json.dumps(dict1)
   print("json output",j)
   #調用api提交信息給短信平台api
   r = requests.post(url_test_api,data=j)
   #輸出調用的api的返回信息,一般返回200
   print("輸出調用api返回結果")
   print(r)
   print(r.text)
   print("輸出結果完畢。")
 except Exception as e:
  print(e)
 return 'ok'

if __name__ == '__main__':
 app1.run(debug=False,host='0.0.0.0',port=5000)
View Code

app2.py:192.168.111.83主機上的python腳本

# -*- coding:utf-8 -*-
from flask import Flask, request
import requests
import json
app = Flask(__name__)
'''
腳本功能:從192.168.111.1獲取到json文件,然原樣輸出。

'''
@app.route('/send', methods=['POST'])
def send():
 try:
  data = json.loads(request.data)   #轉換從alertmanager獲得的json數據為dict類型
  print(data)
 except Exception as e:
  print(e)
 return 'ok'

if __name__ == '__main__':
 app.run(debug=False,host='0.0.0.0',port=5000)
View Code

 

192.168.111.1(api1)端輸出結果。由於json模板的__init__.py文件中的ensure_ascii值設置為True,則中文顯示為代碼,不影響傳輸。結果返回code為200表示調用其他api成功。

E:\學習筆記2019-09\k8s\webhook_py\venv\Scripts\python.exe E:/學習筆記2019-09/k8s/webhook_py/app1.py
 * Serving Flask app "app2" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
json output {"type": "\u76d1\u63a7", "fname": {"\u63d0\u793a\u7c7b\u578b": "firing", "\u544a\u8b66\u4fe1\u606f": "InstanceDown", "\u544a\u8b66\u8282\u70b9": "192.168.111.12"}}
192.168.111.83 - - [22/Jul/2020 16:58:28] "POST /send HTTP/1.1" 200 -
輸出調用api返回結果
<Response [200]>
ok
輸出結果完畢。

  

 192.168.111.85(api2)端輸出結果,在192.168.111.85端能夠正常收到對端傳過來的數據。

[root@prometheus prometheus]# python3 app2.py 
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
{'type': '監控', 'fname': {'提示類型': 'firing', '告警信息': 'InstanceDown', '告警節點': '192.168.111.12'}}
192.168.111.1 - - [22/Jul/2020 17:02:52] "POST /send HTTP/1.1" 200 -

 

 調用其他api時出現如下信息,有可能是你的json模板設置問題。確認下json模板的__init__.py文件中的ensure_ascii值是否為True,如果不為True則需要修改為True。

'latin-1' codec can't encode characters in position 10-11: Body ('監控') is not valid Latin-1. Use body.encode('utf-8') if you want to send it encoded in UTF-8.

json的__init__.py文件位置:

win:   d:/python安裝目錄/Lib/json/__init__.py

linux:  /python安裝目錄//lib/python3.8/json/__init__.py

_default_encoder = JSONEncoder(
    skipkeys=False,
    ensure_ascii=True,
    #ensure_ascii=False,
    check_circular=True,
    allow_nan=True,
    indent=None,
    separators=None,
    default=None,
)

 

alertmanager原始json文件

在192.168.111.1接收到的原始json文件格式,用戶可以根據自己的需求使用key獲取特定的數據。

{
'receiver': 'webhook', 
'status': 'firing', 
'alerts': [
	{'status': 'firing', 
	'labels': {'alertname': 'InstanceDown', 
	'instance': '192.168.111.12:9100', 
	'job': 'consul_111_83', 
	'severity': 'critical'}, 
	'annotations': 
		{'description': 'Host 192.168.111.12:9100 Down', 
		'summary': 'Host 192.168.111.12:9100 of consul_111_83 is  Down !!!'}, 
	'startsAt': '2020-07-22T08:41:22.633075734Z', 
	'endsAt': '0001-01-01T00:00:00Z', 
	'generatorURL': 'http://prometheus.server:9090/graph?g0.expr=up%7Binstance%3D~%2210%7C80%7C192.%2A%22%7D+%3D%3D+0&g0.tab=1', 
	'fingerprint': 'c33ac30fed829472'}], 
'groupLabels': {'instance': '192.168.111.12:9100'}, 
'commonLabels': {'alertname': 'InstanceDown', 
'instance': '192.168.111.12:9100', 
'job': 'consul_111_83', 'severity': 'critical'}, 
'commonAnnotations': 
	{'description': 'Host 192.168.111.12:9100 Down', 
	'summary': 'Host 192.168.111.12:9100 of consul_111_83 is  Down !!!'},
'externalURL': 'http://prometheus.server:9093', 
'version': '4', 
'groupKey': '{}:{instance="192.168.111.12:9100"}', 
'truncatedAlerts': 0
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM