python2.7.5监控php慢日志报警到钉钉机器人

博客介绍了利用Python监控PHP慢日志并将变动内容推送到钉钉的方法。首先在钉钉创建自定义机器人获取Webhook地址,接着安装Python依赖包,准备监控日志的py_inotify.py文件,创建dingding.py和impose.py文件,最后进行测试,成功将文件变动内容推送给钉钉机器人。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、在钉钉创建自定义机器人webhook
在这里插入图片描述
点击“复制”按钮,即可获得这个机器人对应的Webhook地址,其格式如下:
https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx

2、安装python依赖包

pip install pyinotify
pip install requests

3、准备 py_inotify.py,监控php慢日志,如果慢日志有变动,将变动内容发送到钉钉

# !/usr/bin/python
#coding:utf-8
import sys, os, pyinotify
import impose
import datetime
import dingding

notifier = None
monfile = None
lastsize = 0
wm = None
wd = 0


def roll_file(filename):
    global lastsize
    fd = os.open(filename, os.O_RDONLY)
    try:
        newsize = os.fstat(fd).st_size
        if newsize <= lastsize: return
        os.lseek(fd, lastsize, os.SEEK_SET)
        while True:
            data = os.read(fd, 4096)
            if not data: break
            # sys.stdout.write(data)
            impose_number = impose.number(data)
            if impose_number:
                dingding.dingmessage(data)
            else:
                print(datetime.datetime.now().strftime('[%Y-%m-%d %H:%M:%S] ') + "超过调用次数了")
        sys.stdout.flush()

        pos = os.lseek(fd, 0, os.SEEK_CUR)
        lastsize = pos if pos != lastsize else newsize
    finally:
        os.close(fd)


class EventHandler(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        if monfile == event.pathname:
            global wd
            wd = wm.add_watch(monfile, pyinotify.IN_MODIFY).values()[0]
            roll_file(monfile)

    def process_IN_DELETE(self, event):
        global wd, lastsize
        if monfile == event.pathname:
            if wd > 0:
                try:
                    wm.rm_watch(wd, quiet=False)
                except pyinotify.WatchManagerError:
                    pass
                wd = 0
            lastsize = 0

    def process_IN_MOVED_FROM(self, event):
        self.process_IN_DELETE(event)

    def process_IN_MOVED_TO(self, event):
        self.process_IN_DELETE(event)
        self.process_IN_CREATE(event)

    def process_IN_MODIFY(self, event):
        roll_file(monfile)


def main():
    global notifier, lastsize, wm, wd, monfile
    monfile = "./a.txt"
    #print "path={0}".format(monfile)

    lastsize = os.stat(monfile).st_size

    wm = pyinotify.WatchManager()
    notifier = pyinotify.Notifier(wm, EventHandler())
    wd = wm.add_watch(monfile, pyinotify.IN_MODIFY).values()[0]
    wm.add_watch(os.path.dirname(monfile),
                 pyinotify.IN_DELETE | pyinotify.IN_CREATE | pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO)
    #print "watching {0} ...".format(monfile)

    while True:
        notifier.process_events()
        if notifier.check_events():
            notifier.read_events()


if __name__ == "__main__":
    try:
        main()
    finally:
        if notifier: notifier.stop()

4、在py_inotify.py同级目录创建dingding.py

#coding:utf-8
import requests
import json
import sys
import datetime

reload(sys)
sys.setdefaultencoding('utf-8')

def dingmessage(message):
# 请求的URL,WebHook地址
    webhook = "https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxxxxxxxxx"
#构建请求头部
    header = {
        "Content-Type": "application/json",
        "Charset": "UTF-8"
}
#构建请求数据
    tex = message
    message ={

        "msgtype": "text",
        "text": {
            "content": tex
        },
        "at": {

            "isAtAll": True
        }

    }
#对请求的数据进行json封装
    message_json = json.dumps(message)
#发送请求
    info = requests.post(url=webhook,data=message_json,headers=header)
#打印返回的结果
    print(datetime.datetime.now().strftime('[%Y-%m-%d %H:%M:%S] ') + info.text)

5、调用钉钉次数限制,在py_inotify.py同级目录创建impose.py

# -*- coding:utf-8 -*-
import time
import datetime

def stat_called_time(func):
    cache = {}
    limit_times = [18]

    def _called_time(*args, **kwargs):
        key = func.__name__
        #判断是否存在缓存
        if key in cache.keys():
            [call_times, updatetime] = cache[key]
            #过期时间固定为60秒
            if time.time() - updatetime < 60:
                cache[key][0] += 1
            else:
                cache[key] = [1, time.time()]
        else:
            call_times = 1
            cache[key] = [call_times, time.time()]
        # print('调用次数: %s' % cache[key][0])
        # print('限制次数: %s' % limit_times[0])
        if cache[key][0] <= limit_times[0]:
            data = func(*args, **kwargs)
            cache[key][1] = time.time()
            return True
        else:
            print(datetime.datetime.now().strftime('[%Y-%m-%d %H:%M:%S] ') + "超过调用次数了")
            # return None
            return False

    return _called_time


@stat_called_time
def number(data):
    return data

6、测试将文件变动内容发送到钉钉机器人:
python py_inotify.py
钉钉返回结果:
{“errcode”:0,“errmsg”:“ok”}
打开另一个终端:
echo “test dingding” >> a.txt
钉钉接受到消息通知:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值