Python 监控服务器 cpu 及报警,手动执行没有问题,但是后台启动就会有问题,不会发送报警。不知道是什么原因,请大佬给点建议

2021-03-02 14:23:22 +08:00
 longmeier90
import subprocess
import re
import pika
import time, datetime

# 定义删除 ANSI escape code
ansi_escape = re.compile(r'\x1B[@-_][0-?]*[ -/]*[@-~]')

# 消息队列连接
def rabbit_connect():
    credentials = pika.PlainCredentials("admin", "bolin1024")
    connection = pika.BlockingConnection(pika.ConnectionParameters(
        host="39.96.5.133", port=5672, credentials=credentials))  # 定义连接池
    channel = connection.channel()  # 声明队列以向其发送消息消息
    return channel, connection

# 消息队列关闭
def rabbit_close(connection):
    connection.close()

# 消息队列发送消息
def create_msg(channel, msg):
    """
    消息发送方
    :param msg:
    :return:
    """

    # durable server 挂了 队列仍然存在
    channel.queue_declare(queue="cpu_monitor", durable=True)
    # delivery_mode=2:使消息持久化。和队列名称绑定 routing_key
    channel.basic_publish(exchange='', routing_key="cpu_monitor", body=msg,
                          properties=pika.BasicProperties(delivery_mode=2))


# 监控程序
def monitor_process():


    top_info = subprocess.Popen(["top", "-n", "1"], stdout=subprocess.PIPE)
    out, err = top_info.communicate()
    out_info = out.decode('unicode-escape')
    lines, result = [], []
    lines = out_info.split('\n')
    if len(lines) >= 13:
        load_average = lines[0]
        load_aver = load_average.split()
        loads = [ansi_escape.sub('', col).upper().replace("\x1b(B", '') for col in load_aver]
        loads = list(filter(None, loads))
        loads_cpu0 = float(loads[11].replace(',', '').strip()) if len(loads) > 11 else 4
        for l in range(7, 13):
            hang = str(lines[l])
            hangs = hang.split()
            hangs = [ansi_escape.sub('', col).upper().replace("\x1b(B", '') for col in hangs]
            hangs = list(filter(None, hangs))
            if len(hangs) > 11:
                pid = hangs[0]
                user = hangs[1]
                cpu = hangs[8]
                mem = hangs[9]
                apps = hangs[11]
                if float(cpu) > 80 and 'MYSQL' not in apps and loads_cpu0 > 4:
                    print(pid, user, cpu, mem, apps, loads_cpu0) 
                    print('请开始报警....', cpu)
                    spy_info = subprocess.Popen(["py-spy","dump","--pid", pid], stdout=subprocess.PIPE)
                    out2, err2 = spy_info.communicate()
                    out_info2 = out2.decode('unicode-escape')
                    lines2 = []
                    lines2 = out_info2.split('\n')
                    for l in range(len(lines2)):
                        hang2 = str(lines2[l])
                        print(hang2)
                        hangs2 = hang2.split("(")
                        if len(hangs2) > 1:
                            meth = hangs2[0].strip()
                            path = hangs2[1].split(")")[0].strip()
                            if meth == "get" and "/views/" in path:
                                meta = {'name': path, 'cpu': cpu, 'loads_cpu0': loads_cpu0}
                                print(meta)
                                result.append(meta)
    # 如果存在要发送的消息
    if len(result) > 0:
        channel_, connection_ = rabbit_connect()
        for rt in result:
            create_msg(channel_, str(meta))
        rabbit_close(connection_)


if __name__ == "__main__":

    print('cpu 报警程序已启动....')
    
    while True:
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        print('%s cpu 报警程序 monitor_process...' % now_time)
        try:
            monitor_process()
        except Exception as e:
            print(e)
            
        time.sleep(20)
948 次点击
所在节点    Python
4 条回复
program9527
2021-03-02 14:32:16 +08:00
整个代码中使用了两处 subprocess.Popen,手动启动时,你的终端会加载用户目录下的 .bashrc 文件,也就是环境变量。在后台启动可能不会加载,从而导致一些系统调用无法正确找到命令。例如你上面的一行:

subprocess.Popen(["py-spy","dump","--pid", pid]

建议排查下。。。
program9527
2021-03-02 14:33:04 +08:00
把这种系统调用改成绝对路径试试
lmaq
2021-03-02 14:43:41 +08:00
改下管理员密码吧,暴漏了!
longmeier90
2021-03-02 14:45:00 +08:00
@lmaq 不知道不能删帖,太坑啦。马上就改

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/757617

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX