
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) 1 program9527 Mar 2, 2021 整个代码中使用了两处 subprocess.Popen,手动启动时,你的终端会加载用户目录下的 .bashrc 文件,也就是环境变量。在后台启动可能不会加载,从而导致一些系统调用无法正确找到命令。例如你上面的一行: subprocess.Popen(["py-spy","dump","--pid", pid] 建议排查下。。。 |
2 program9527 Mar 2, 2021 把这种系统调用改成绝对路径试试 |
3 lmaq Mar 2, 2021 改下管理员密码吧,暴漏了! |
4 longmeier90 OP @lmaq 不知道不能删帖,太坑啦。马上就改 |