暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Prometheus+Grafana+Webhook实现钉钉告警

IT那活儿 2025-08-21
411
点击上方“IT那活儿”公众号--专注于企业全栈运维技术分享,不管IT什么活儿,干就完了!!!


部署前准备

1.1 系统要求
确保服务器为Linux系统如CentOS或Ubuntu),具有足够的资源(内存、磁盘空间等)。例如,推荐至少2GB内存用于小规模部署。
1.2 软件安装包
下载Prometheus二进制文件,可从官方网站获取适合系统版本的文件。
Grafana可从其官网下载对应的安装包,如对于CentOS可通过yum源安装或者下载二进制包部署。
1.3 网络配置
服务器需要有公网IP或者在内网中可被访问的IP地址,以方便数据采集和外部访问。


Prometheus部署

2.1 解压安装包
将下载的Prometheus安装包解压到指定目录,例如 /usr/local/prometheus
2.2 配置文件
编辑 prometheus.yml 配置文件,定义监控目标的地址、采集规则等。
例如:
这里定义了设置了一个名为 zhulong_port_status 的采集任务,采集目标机器任意指定端口(Prometheus的blackbox黑盒tcp探测
2.3 启动Prometheus
在解压目录下执行 ./prometheus --config.file=prometheus.yml 启动服务。


Grafana部署

3.1 安装(以CentOS为例)
如果通过yum源安装,先导入Grafana的yum仓库密钥,然后安装 grafana 软件包。
3.2 配置
启动Grafana后,访问 http://[服务器IP]:3000,使用默认用户名和密码(admin/admin)登录。
在Grafana中添加Prometheus数据源,填写Prometheus服务器的地址(如 http://[Prometheus服务器IP]:9090
3.3 创建仪表盘
登录后,可以根据需求创建仪表盘,从Prometheus数据源中选取指标来构建可视化图表。例如,可以创建一个显示CPU使用率的图表,或者其他自定义图标


Webhook集成

4.1 配置Webhook目标
在Grafana中,当前监测的目标主机:端口不通的时候进行处罚告警。可以配置Webhook。在Grafana的告警通知渠道中添加Webhook类型的目标,填写接收通知的URL如一个自定义的服务器端点
创建grafana规则,使用自己环境适配的promql查看出异常数据。根据策略将告警输出到webhook。
4.2 接收Webhook的服务器端
可以使用多种编程语言实现Webhook接收端,如Python的Flask框架。
示例代码:仅供参考,部分细节需要根据自己环境增删改

from flask import Flask, request
from dateutil import parser
import json
import datetime
import yaml
import os
from gevent.pywsgi import WSGIServer
from ding_talk import *
from log_write import *


deftime_zone_conversion(utctime):
    format_time = parser.parse(utctime).strftime('%Y-%m-%dT%H:%M:%SZ')
    time_format = datetime.datetime.strptime(format_time, "%Y-%m-%dT%H:%M:%SZ")
    return str(time_format + datetime.timedelta(hours=8))

defget_phone_conf(file, phone_name=None, action=0):
    """
    :param file: yaml格式的文件类型
    :param phone_name: 发送的邮件列表名
    :param action: 操作类型,0: 查询收件人的邮件地址列表, 1: 查询收件人的列表名称, 2: 获取邮件账号信息
    :return: 根据action的值,返回不通的数据结构
    """

    try:
        with open(os.path.split(os.path.realpath(__file__))[0]+'/'+file, 'r', encoding='utf-8'as fr:
            read_conf = yaml.safe_load(fr)
            if action == 0:
                for phone in read_conf['phone']:
                    if phone['name'] == phone_name:
                        return phone['receive_addr']
                    else:
                        print("%s does not match for %s" % (phone_name, file))
                else:
                    print("No recipient address configured")
            elif action == 1:
                return [items['name'for items in read_conf['phone']]
            elif action == 2:
                return read_conf['send']
    except KeyError:
        print("%s not exist" % phone_name)
        exit(-1)
    except FileNotFoundError:
        print("%s file not found" % file)
        exit(-2)
    except Exception as e:
        raise e
    
app = Flask(__name__)
@app.route('/show', methods=['POST'])
defdatatest():
    try:
        prometheus_data = json.loads(request.data)
        logger.info(str(request.data,'utf-8'))
        return"请观察控制台输出"
    except Exception as e:
        raise e
    
@app.route('/webhook', methods=['POST'])
defwebhook():
    try:
        prometheus_data = json.loads(request.data)
        logger.info(str(request.data,'utf-8'))
        #print(request.json)
        # 时间转换,转换成东八区时间
        for k, v in prometheus_data.items():
            if k == 'alerts':
                for items in v:
                    # if items['status'] == 'firing':
                    # items['startsAt'] = time_zone_conversion(items['startsAt'])
                    # else:
                    # items['startsAt'] = time_zone_conversion(items['startsAt'])
                    # items['endsAt'] = time_zone_conversion(items['endsAt'])
                    #针对每个itemss进行告警通知
                    team_name = prometheus_data["commonLabels"]["team"]
                    phone_list = get_phone_conf('config.yaml', phone_name=team_name, action=0)
                    level = prometheus_data["commonLabels"]["severity"]

                    data = data_format(items,phone_list,level)
                    send_ding_talk(data)
        return"prometheus monitor"
    except Exception as e:
        raise e
if __name__ == '__main__':
    logger = setup_log('prom_dingtalk.log')
    WSGIServer(('0.0.0.0'5000), app).serve_forever()

以上webhook通过调用钉钉的自定义模块进行告警输出。相应的调用部分可以根据自己环境调整。
4.3 测试
在Grafana中触发告警条件,检查接收端是否正确接收到Webhook通知,并且相关操作(如告警通知到运维人员等)是否按预期执行。
通过以上步骤,可以完成Prometheus + Grafana+Webhook的部署,实现对系统指标的监控和基于阈值的自动化通知处理。

END


本文作者:黄 凭(上海新炬中北团队)

本文来源:“IT那活儿”公众号

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论