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