• 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
    }
  • 相关阅读:
    转载两篇文章之二(从程序员到CTO所要培养的六种能力)作者:阿蒙 原文:http://blog.csdn.net/harrymeng/archive/2007/02/07/1503931.aspx
    关于解决eclipse中的插件依赖
    GMF中控制Figure的大小和位置
    Sql server2005中如何格式化时间日期
    JavaScript创建对象的几种方式
    FCK编辑器焦点问题
    对引用类型的一点理解
    利用XML FOR PATH 合并分组信息
    [译]Silverlight中TreeView增删改查和拖放
    KeyedCollection<TKey, TItem>与IDictionary<TKey, TValue>的区别
  • 原文地址:https://www.cnblogs.com/Pigs-Will-Fly/p/13361527.html
Copyright © 2020-2023  润新知