mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-20 06:35:47 +02:00
557 lines
26 KiB
Python
557 lines
26 KiB
Python
import json
|
|
import os
|
|
import time
|
|
import traceback
|
|
import re
|
|
import psutil
|
|
|
|
import public
|
|
from monitorModel.base import monitorBase
|
|
from pluginAuth import Plugin
|
|
|
|
|
|
class main(monitorBase):
|
|
setupPath = '/www/server'
|
|
__panel_path = '/www/server/panel/class/monitorModel'
|
|
__data_path = os.path.join(__panel_path, 'data')
|
|
cpu_old_path = os.path.join(__data_path, 'cpu_old.json')
|
|
disk_read_old_path = os.path.join(__data_path, 'disk_read_old.json')
|
|
disk_write_old_path = os.path.join(__data_path, 'disk_write_old.json')
|
|
old_net_path = os.path.join(__data_path, 'network_old.json')
|
|
old_disk_path = os.path.join(__data_path, 'disk_old.json')
|
|
old_site_path = os.path.join(__data_path, 'site_old.json')
|
|
nethogs_out = os.path.join(__data_path, 'process_flow.log')
|
|
|
|
disk_write_new_info = {}
|
|
disk_write_old_info = {}
|
|
disk_read_new_info = {}
|
|
disk_read_old_info = {}
|
|
cpu_new_info = {}
|
|
old_disk_info = {}
|
|
new_disk_info = {}
|
|
cpu_old_info = {}
|
|
log_path = {
|
|
"mongod": "/www/server/mongodb/log/config.log",
|
|
"nginx": "/www/wwwlogs/nginx_error.log",
|
|
"httpd": "/www/wwwlogs/nginx_error.log",
|
|
"mysqld": "/www/server/data/mysql-slow.log",
|
|
}
|
|
|
|
pids = None
|
|
__cpu_time = None
|
|
panel_pid = None
|
|
task_pid = None
|
|
processPs = {
|
|
'bioset': '用于处理块设备上的I/O请求的进程',
|
|
'BT-MonitorAgent': '面板程序的进程',
|
|
'rngd': '一个熵守护的进程',
|
|
'master': '用于管理和协调子进程的活动的进程',
|
|
'irqbalance': '一个IRQ平衡守护的进程',
|
|
'rhsmcertd': '主要用于管理Red Hat订阅证书,并维护系统的订阅状态的进程',
|
|
'auditd': '是Linux审计系统中用户空间的一个组的进程',
|
|
'chronyd': '调整内核中运行的系统时钟和时钟服务器同步的进程',
|
|
'qmgr': 'PBS管理器的进程',
|
|
'oneavd': '面板微步木马检测的进程',
|
|
'postgres': 'PostgreSQL数据库的进程',
|
|
'grep': '一个命令行工具的进程',
|
|
'lsof': '一个命令行工具的进程',
|
|
'containerd-shim-runc-v2': 'Docker容器的一个组件的进程',
|
|
'pickup': '用于监听Unix域套接字的进程',
|
|
'cleanup': '邮件传输代理(MTA)中的一个组件的进程',
|
|
'trivial-rewrite': '邮件传输代理(MTA)中的一个组件的进程',
|
|
'containerd': 'docker依赖服务的进程',
|
|
'redis-server': 'redis服务的进程',
|
|
'rcu_sched': 'linux系统rcu机制服务的进程',
|
|
'jsvc': '面板tomcat服务的进程',
|
|
'oneav': '面板微步木马检测的进程',
|
|
'mysqld': 'MySQL服务的进程',
|
|
'php-fpm': 'PHP的子进程',
|
|
'php-cgi': 'PHP-CGI的进程',
|
|
'nginx': 'Nginx服务的进程',
|
|
'httpd': 'Apache服务的进程',
|
|
'sshd': 'SSH服务的进程',
|
|
'pure-ftpd': 'FTP服务的进程',
|
|
'sftp-server': 'SFTP服务的进程',
|
|
'mysqld_safe': 'MySQL服务的进程',
|
|
'firewalld': '防火墙服务的进程',
|
|
'BT-Panel': '宝塔面板-主的进程',
|
|
'BT-Task': '宝塔面板-后台任务的进程',
|
|
'NetworkManager': '网络管理服务的进程',
|
|
'svlogd': '日志守护的进程',
|
|
'memcached': 'Memcached缓存器的进程',
|
|
'gunicorn': "宝塔面板的进程",
|
|
"BTPanel": '宝塔面板的进程',
|
|
'baota_coll': "堡塔云控-主控端的进程",
|
|
'baota_client': "堡塔云控-被控端的进程",
|
|
'node': 'Node.js程序的进程',
|
|
'supervisord': 'Supervisor的进程',
|
|
'rsyslogd': 'rsyslog日志服务的进程',
|
|
'crond': '计划任务服务的进程',
|
|
'cron': '计划任务服务的进程',
|
|
'rsync': 'rsync文件同步的进程',
|
|
'ntpd': '网络时间同步服务的进程',
|
|
'rpc.mountd': 'NFS网络文件系统挂载服务的进程',
|
|
'sendmail': 'sendmail邮件服务的进程',
|
|
'postfix': 'postfix邮件服务的进程',
|
|
'npm': 'Node.js NPM管理器的进程',
|
|
'PM2': 'Node.js PM2进程管理器的进程',
|
|
'htop': 'htop进程监控软件的进程',
|
|
'btpython': '宝塔面板-独立Python环境的进程',
|
|
'btappmanagerd': '宝塔应用管理器插件的进程',
|
|
'dockerd': 'Docker容器管理器的进程',
|
|
'docker-proxy': 'Docker容器管理器的进程',
|
|
'docker-registry': 'Docker容器管理器的进程',
|
|
'docker-distribution': 'Docker容器管理器的进程',
|
|
'docker-network': 'Docker容器管理器的进程',
|
|
'docker-volume': 'Docker容器管理器的进程',
|
|
'docker-swarm': 'Docker容器管理器的进程',
|
|
'docker-systemd': 'Docker容器管理器的进程',
|
|
'docker-containerd': 'Docker容器管理器的进程',
|
|
'docker-containerd-shim': 'Docker容器管理器的进程',
|
|
'docker-runc': 'Docker容器管理器的进程',
|
|
'docker-init': 'Docker容器管理器的进程',
|
|
'docker-init-systemd': 'Docker容器管理器的进程',
|
|
'docker-init-upstart': 'Docker容器管理器的进程',
|
|
'docker-init-sysvinit': 'Docker容器管理器的进程',
|
|
'docker-init-openrc': 'Docker容器管理器的进程',
|
|
'docker-init-runit': 'Docker容器管理器的进程',
|
|
'docker-init-systemd-resolved': 'Docker容器管理器的进程',
|
|
'rpcbind': 'NFS网络文件系统服务的进程',
|
|
'dbus-daemon': 'D-Bus消息总线守护的进程',
|
|
'systemd-logind': '登录管理器的进程',
|
|
'systemd-journald': 'Systemd日志管理服务的进程',
|
|
'systemd-udevd': '系统设备管理服务的进程',
|
|
'systemd-timedated': '系统时间日期服务的进程',
|
|
'systemd-timesyncd': '系统时间同步服务的进程',
|
|
'systemd-resolved': '系统DNS解析服务的进程',
|
|
'systemd-hostnamed': '系统主机名服务的进程',
|
|
'systemd-networkd': '系统网络管理服务的进程',
|
|
'systemd-resolvconf': '系统DNS解析服务的进程',
|
|
'systemd-local-resolv': '系统DNS解析服务的进程',
|
|
'systemd-sysctl': '系统系统参数服务的进程',
|
|
'systemd-modules-load': '系统模块加载服务的进程',
|
|
'systemd-modules-restore': '系统模块恢复服务的进程',
|
|
'agetty': 'TTY登陆验证程序的进程',
|
|
'sendmail-mta': 'MTA邮件传送代理的进程',
|
|
'(sd-pam)': '可插入认证模块的进程',
|
|
'polkitd': '授权管理服务的进程',
|
|
'mongod': 'MongoDB数据库服务的进程',
|
|
'mongodb': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-monitor': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-backup': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-restore': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-agent': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-analytics': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-tools': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-backup-agent': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-backup-tools': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-restore-agent': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-restore-tools': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-analytics-agent': 'MongoDB数据库服务的进程',
|
|
'mongodb-mms-analytics-tools': 'MongoDB数据库服务的进程',
|
|
'dhclient': 'DHCP协议客户端的进程',
|
|
'dhcpcd': 'DHCP协议客户端的进程',
|
|
'dhcpd': 'DHCP服务器的进程',
|
|
'isc-dhcp-server': 'DHCP服务器的进程',
|
|
'isc-dhcp-server6': 'DHCP服务器的进程',
|
|
'dhcp6c': 'DHCP服务器的进程',
|
|
'dhcpcd': 'DHCP服务器的进程',
|
|
'dhcpd': 'DHCP服务器的进程',
|
|
'avahi-daemon': 'Zeroconf守护的进程',
|
|
'login': '登录的进程',
|
|
'systemd': '系统管理服务的进程',
|
|
'systemd-sysv': '系统管理服务的进程',
|
|
'systemd-journal-gateway': '系统管理服务的进程',
|
|
'systemd-journal-remote': '系统管理服务的进程',
|
|
'systemd-journal-upload': '系统管理服务的进程',
|
|
'systemd-networkd': '系统网络管理服务的进程',
|
|
'rpc.idmapd': 'NFS网络文件系统相关服务的进程',
|
|
'cupsd': '打印服务的进程',
|
|
'cups-browsed': '打印服务的进程',
|
|
'sh': 'shell的进程',
|
|
'php': 'PHP CLI模式的进程',
|
|
'blkmapd': 'NFS映射服务的进程',
|
|
'lsyncd': '文件同步服务的进程',
|
|
'sleep': '延迟的进程',
|
|
}
|
|
|
|
def __init__(self):
|
|
if not os.path.isdir(self.__data_path):
|
|
os.makedirs(self.__data_path, 384)
|
|
plugin_obj = Plugin(False)
|
|
plugin_list = plugin_obj.get_plugin_list()
|
|
public.print_log(plugin_list['ltd'])
|
|
ped = int(plugin_list['ltd']) > time.time()
|
|
if ped:
|
|
self.add_nethogs_task()
|
|
|
|
def specific_resource_load_type(self, get):
|
|
"""
|
|
查询具体资源类型负载
|
|
:param get: None
|
|
:return: 资源占用字典
|
|
"""
|
|
try:
|
|
plugin_obj = Plugin(False)
|
|
plugin_list = plugin_obj.get_plugin_list()
|
|
public.print_log(plugin_list['ltd'])
|
|
ped = int(plugin_list['ltd']) > time.time()
|
|
if not ped: return {'status': False, 'msg': "该功能为企业版专享!"}
|
|
infos = {}
|
|
load_avg = os.getloadavg()
|
|
infos['info'] = {}
|
|
infos['info']['physical_cpu'] = psutil.cpu_count(logical=False)
|
|
infos['info']['logical_cpu'] = psutil.cpu_count(logical=True)
|
|
c_tmp = public.readFile('/proc/cpuinfo')
|
|
d_tmp = re.findall("physical id.+", c_tmp)
|
|
cpuW = len(set(d_tmp))
|
|
infos['info']['cpu_name'] = public.getCpuType() + " * {}".format(cpuW)
|
|
infos['info']['num_phys_cores'] = cpuW
|
|
infos['info']['load_avg'] = {"1": load_avg[0], "5": load_avg[1], "15": load_avg[2]}
|
|
infos['info']['active_processes'] = len(
|
|
[p for p in psutil.process_iter() if p.status() == psutil.STATUS_RUNNING])
|
|
infos['info']['total_processes'] = len(psutil.pids())
|
|
cpu_percent = self.get_process_cpu(get)
|
|
cpu_proc = cpu_percent["process_list"]
|
|
mem = self.get_mem_info()
|
|
infos['CPU_percentage_of_load'] = cpu_percent["info"]["cpu"]
|
|
infos['percentage_of_memory_usage'] = round(mem['memRealUsed'] / mem['memTotal'] * 100, 2)
|
|
infos['CPU_high_occupancy_software_list'] = {}
|
|
for i in range(5):
|
|
try:
|
|
infos['CPU_high_occupancy_software_list'][i] = {"name": cpu_proc[i]['name'],
|
|
'pid': cpu_proc[i]['pid'],
|
|
'cpu_percent': cpu_proc[i]['cpu_percent'],
|
|
'proc_survive': cpu_proc[i]['proc_survive']}
|
|
except:
|
|
pass
|
|
b = []
|
|
for i, j in infos['CPU_high_occupancy_software_list'].items():
|
|
cpu_info = {'proc_name': infos['CPU_high_occupancy_software_list'][i]['name'],
|
|
'pid': infos['CPU_high_occupancy_software_list'][i]['pid'],
|
|
'cpu_percent': str(infos['CPU_high_occupancy_software_list'][i]['cpu_percent']) + "%"}
|
|
cpu_info['explain'], cpu_info['num_threads'], cpu_info['exe_path'], cpu_info['cwd_path'], cpu_info[
|
|
'important'], cpu_info['proc_survive'] = self.__process_analysis(
|
|
infos['CPU_high_occupancy_software_list'][i]['pid'])
|
|
b.append(cpu_info)
|
|
infos['CPU_high_occupancy_software_list'] = b
|
|
infos["memory_high_occupancy_software_list"] = self.__use_mem_list()
|
|
c = []
|
|
for i, j in infos["memory_high_occupancy_software_list"].items():
|
|
mem_info = {'proc_name': i, 'pid': infos['memory_high_occupancy_software_list'][i]['pid'],
|
|
"memory_usage": infos["memory_high_occupancy_software_list"][i]['memory_usage']}
|
|
mem_info['explain'], mem_info['num_threads'], mem_info['exe_path'], mem_info['cwd_path'], mem_info[
|
|
'important'], mem_info['proc_survive'] = self.__process_analysis(
|
|
infos["memory_high_occupancy_software_list"][i]['pid'])
|
|
c.append(mem_info)
|
|
infos["memory_high_occupancy_software_list"] = c
|
|
return infos
|
|
except:
|
|
public.print_log(traceback.format_exc())
|
|
|
|
# 按cpu资源获取进程列表
|
|
def get_process_cpu(self, get):
|
|
self.pids = psutil.pids()
|
|
process_list = []
|
|
if type(self.cpu_new_info) != dict: self.cpu_new_info = {}
|
|
self.cpu_new_info['cpu_time'] = self.get_cpu_time()
|
|
self.cpu_new_info['time'] = time.time()
|
|
|
|
if 'sort' not in get: get.sort = 'cpu_percent'
|
|
get.reverse = bool(int(get.reverse)) if 'reverse' in get else True
|
|
info = {}
|
|
info['activity'] = 0
|
|
info['cpu'] = 0.00
|
|
status_ps = {'sleeping': '睡眠', 'running': '活动'}
|
|
limit = 1000
|
|
for pid in self.pids:
|
|
tmp = {}
|
|
try:
|
|
p = psutil.Process(pid)
|
|
except:
|
|
continue
|
|
with p.oneshot():
|
|
p_cpus = p.cpu_times()
|
|
p_state = p.status()
|
|
if p_state == 'running': info['activity'] += 1
|
|
if p_state in status_ps:
|
|
p_state = status_ps[p_state]
|
|
else:
|
|
continue
|
|
tmp['exe'] = p.exe()
|
|
timestamp = time.time() - p.create_time()
|
|
time_info = {}
|
|
time_info["天"] = int(timestamp // (24 * 3600))
|
|
time_info["小时"] = int((timestamp - time_info['天'] * 24 * 3600) // 3600)
|
|
time_info["分钟"] = int((timestamp - time_info['天'] * 24 * 3600 - time_info['小时'] * 3600) // 60)
|
|
ll = [str(v) + k for k, v in time_info.items() if v != 0]
|
|
tmp['proc_survive'] = ''.join(ll)
|
|
tmp['name'] = p.name()
|
|
tmp['pid'] = pid
|
|
tmp['ppid'] = p.ppid()
|
|
# tmp['create_time'] = int(p.create_time())
|
|
tmp['status'] = p_state
|
|
tmp['user'] = p.username()
|
|
tmp['cpu_percent'] = self.get_cpu_percent(str(pid), p_cpus, self.cpu_new_info['cpu_time'])
|
|
tmp['threads'] = p.num_threads()
|
|
tmp['ps'] = self.get_process_ps(tmp['name'], pid)
|
|
if tmp['cpu_percent'] > 100: tmp['cpu_percent'] = 0.1
|
|
info['cpu'] += tmp['cpu_percent']
|
|
process_list.append(tmp)
|
|
limit -= 1
|
|
if limit <= 0: break
|
|
del p
|
|
del tmp
|
|
public.writeFile(self.cpu_old_path, json.dumps(self.cpu_new_info))
|
|
# process_list = self.handle_process_list(process_list)
|
|
process_list = sorted(process_list, key=lambda x: x[get.sort], reverse=get.reverse)
|
|
info['load_average'] = self.get_load_average()
|
|
data = {}
|
|
data['process_list'] = process_list[:10]
|
|
info['cpu'] = round(info['cpu'], 2)
|
|
data['info'] = info
|
|
return data
|
|
|
|
# 获取负载
|
|
def get_load_average(self, get=None):
|
|
b = public.ExecShell("uptime")[0].replace(',', '')
|
|
c = b.split()
|
|
data = {}
|
|
data['1'] = float(c[-3])
|
|
data['5'] = float(c[-2])
|
|
data['15'] = float(c[-1])
|
|
return data
|
|
|
|
# 获取总的cpu时间
|
|
def get_cpu_time(self, get=None):
|
|
if self.__cpu_time: return self.__cpu_time
|
|
self.__cpu_time = 0.00
|
|
s = psutil.cpu_times()
|
|
self.__cpu_time = s.user + s.system + s.nice + s.idle
|
|
return self.__cpu_time
|
|
|
|
# 获取进程cpu利用率
|
|
def get_cpu_percent(self, pid, cpu_times, cpu_time):
|
|
self.get_cpu_old()
|
|
percent = 0.00
|
|
process_cpu_time = self.get_process_cpu_time(cpu_times)
|
|
if not self.cpu_old_info: self.cpu_old_info = {}
|
|
if pid not in self.cpu_old_info:
|
|
self.cpu_new_info[pid] = {}
|
|
self.cpu_new_info[pid]['cpu_time'] = process_cpu_time
|
|
return percent
|
|
percent = round(100.00 * (process_cpu_time - self.cpu_old_info[pid]['cpu_time']) / (
|
|
cpu_time - self.cpu_old_info['cpu_time']), 2)
|
|
self.cpu_new_info[pid] = {}
|
|
self.cpu_new_info[pid]['cpu_time'] = process_cpu_time
|
|
if percent > 0: return percent
|
|
return 0.00
|
|
|
|
# 获取信息,如果存在返回true,不存在读取gson后存在true:不存在flase
|
|
def get_cpu_old(self):
|
|
if self.cpu_old_info: return True
|
|
if not os.path.exists(self.cpu_old_path): return False
|
|
data = public.readFile(self.cpu_old_path)
|
|
if not data: return False
|
|
data = json.loads(data)
|
|
if not data: return False
|
|
self.cpu_old_info = data
|
|
del data
|
|
return True
|
|
|
|
# 获取进程占用的cpu时间
|
|
def get_process_cpu_time(self, cpu_times):
|
|
cpu_time = 0.00
|
|
for s in cpu_times: cpu_time += s
|
|
return cpu_time
|
|
|
|
def get_process_ps(self, name, pid):
|
|
if name in self.processPs: return self.processPs[name]
|
|
|
|
# 增加使用nethogs收集进程流量定时任务
|
|
def add_nethogs_task(self, get=None):
|
|
# self.add_process_white('nethogs')
|
|
import crontab
|
|
if public.M('crontab').where('name=?', u'[勿删]资源管理器-获取进程流量').count():
|
|
return public.returnMsg(True, '定时任务已存在!')
|
|
|
|
s_body = '''ps -ef | grep nethogs | grep -v grep | awk '{print $2}' | xargs kill 2>/dev/null
|
|
count=0
|
|
while [ $count -lt 2 ]
|
|
do
|
|
count=$(($count+1))
|
|
/usr/sbin/nethogs -t -a -d 2 -c 5 > %s 2>/dev/null
|
|
if [[ $count == 2 ]];then
|
|
exit
|
|
else
|
|
sleep 20
|
|
fi
|
|
done''' % self.nethogs_out
|
|
|
|
p = crontab.crontab()
|
|
args = {
|
|
"name": u'[勿删]资源管理器-获取进程流量',
|
|
"type": 'minute-n',
|
|
"where1": 5,
|
|
"hour": '',
|
|
"minute": '',
|
|
"week": '',
|
|
"sType": "toShell",
|
|
"sName": "",
|
|
"backupTo": "",
|
|
"save": '',
|
|
"sBody": s_body,
|
|
"urladdress": "undefined"
|
|
}
|
|
p.AddCrontab(args)
|
|
return public.returnMsg(True, '设置成功!')
|
|
|
|
# 获取内存情况
|
|
def get_mem_info(self, get=None):
|
|
mem = psutil.virtual_memory()
|
|
memInfo = {'memTotal': int(mem.total / 1024 / 1024), 'memFree': int(mem.free / 1024 / 1024),
|
|
'memBuffers': int(mem.buffers / 1024 / 1024), 'memCached': int(mem.cached / 1024 / 1024)}
|
|
memInfo['memRealUsed'] = memInfo['memTotal'] - memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached']
|
|
return memInfo
|
|
|
|
def __use_mem_list(self):
|
|
processes = []
|
|
for proc in psutil.process_iter():
|
|
try:
|
|
# 获取进程详细信息
|
|
pinfo = proc.as_dict(attrs=['pid', 'name', 'memory_info'])
|
|
# 添加到进程列表
|
|
processes.append(pinfo)
|
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
pass
|
|
processes = sorted(processes, key=lambda p: p['memory_info'].rss, reverse=True)
|
|
l = {}
|
|
mem_total = psutil.virtual_memory().total
|
|
for p in processes:
|
|
l[p['name']] = {'pid': p['pid'],
|
|
'memory_usage': '%.2f' % (int(p['memory_info'].rss) / int(mem_total) * 100) + "%"}
|
|
if len(l) >= 5:
|
|
break
|
|
return l
|
|
|
|
# 常用软件分析
|
|
def __process_analysis(self, pid):
|
|
process = psutil.Process(pid)
|
|
important = 0
|
|
explain = self.processPs.get(process.name(),
|
|
'未知程序的进程')
|
|
if 'BT-Panel' == process.name() or 'BT-Task' == process.name():
|
|
important = 1
|
|
num_threads = process.num_threads()
|
|
exe_path = process.exe()
|
|
cwd_path = process.cwd()
|
|
timestamp = time.time() - process.create_time()
|
|
time_info = {}
|
|
time_info["天"] = int(timestamp // (24 * 3600))
|
|
time_info["小时"] = int((timestamp - time_info['天'] * 24 * 3600) // 3600)
|
|
time_info["分钟"] = int((timestamp - time_info['天'] * 24 * 3600 - time_info['小时'] * 3600) // 60)
|
|
ll = [str(v) + k for k, v in time_info.items() if v != 0]
|
|
pro_time = ''.join(ll)
|
|
if ''.join(ll) == '':
|
|
pro_time = '小于1分钟'
|
|
return explain, num_threads, exe_path, cwd_path, important, pro_time
|
|
|
|
def kill_process_all(self, get):
|
|
pid = int(get.pid)
|
|
if pid < 30: return public.returnMsg(False, '不能结束系统关键进程!')
|
|
if pid not in psutil.pids(): return public.returnMsg(False, '指定进程不存在!')
|
|
p = psutil.Process(pid)
|
|
if self.is_panel_process(pid): return public.returnMsg(False, '不能结束面板服务进程')
|
|
p.kill()
|
|
return self.kill_process_tree_all(pid)
|
|
|
|
# 结束进程树
|
|
def kill_process_tree_all(self, pid):
|
|
if pid < 30: return public.returnMsg(True, '已结束此进程树!')
|
|
if self.is_panel_process(pid): return public.returnMsg(False, '不能结束面板服务进程')
|
|
try:
|
|
if pid not in psutil.pids(): public.returnMsg(True, '已结束此进程树!')
|
|
p = psutil.Process(pid)
|
|
ppid = p.ppid()
|
|
name = p.name()
|
|
p.kill()
|
|
public.ExecShell('pkill -9 ' + name)
|
|
if name.find('php-') != -1:
|
|
public.ExecShell("rm -f /tmp/php-cgi-*.sock")
|
|
elif name.find('mysql') != -1:
|
|
public.ExecShell("rm -f /tmp/mysql.sock")
|
|
elif name.find('mongod') != -1:
|
|
public.ExecShell("rm -f /tmp/mongod*.sock")
|
|
self.kill_process_lower(pid)
|
|
if ppid: return self.kill_process_all(ppid)
|
|
except:
|
|
pass
|
|
return public.returnMsg(True, '已结束此进程树!')
|
|
|
|
def kill_process_lower(self, pid):
|
|
pids = psutil.pids()
|
|
for lpid in pids:
|
|
if lpid < 30: continue
|
|
if self.is_panel_process(lpid): continue
|
|
p = psutil.Process(lpid)
|
|
ppid = p.ppid()
|
|
if ppid == pid:
|
|
p.kill()
|
|
return self.kill_process_lower(lpid)
|
|
return True
|
|
|
|
# 判断是否是面板进程
|
|
def is_panel_process(self, pid):
|
|
if not self.panel_pid:
|
|
self.panel_pid = os.getpid()
|
|
if pid == self.panel_pid: return True
|
|
if not self.task_pid:
|
|
try:
|
|
self.task_pid = int(
|
|
public.ExecShell("ps aux | grep 'python task.py'|grep -v grep|head -n1|awk '{print $2}'")[0])
|
|
except:
|
|
self.task_pid = -1
|
|
if pid == self.task_pid: return True
|
|
return False
|
|
|
|
def __get_number_of_processes(self):
|
|
import psutil
|
|
from collections import Counter
|
|
ll = []
|
|
processes = psutil.process_iter()
|
|
process_names = [process.name() for process in processes]
|
|
process_item = Counter(process_names)
|
|
process_item = dict(sorted(process_item.items(), key=lambda item: item[1], reverse=True)[:5])
|
|
for key, value in process_item.items():
|
|
procs = {'proc_name': key, 'proc_description': '此进程的进程数有' + str(value) + '个,进程是{}'.format(
|
|
self.processPs.get(key, "未知进程"))}
|
|
ll.append(procs)
|
|
return ll
|
|
|
|
def process_description(self, get):
|
|
try:
|
|
updatas = json.loads(get.information_collection)
|
|
data = json.loads(public.readFile('/www/server/panel/class/monitorModel/common_process.json'))
|
|
data.update(updatas)
|
|
public.writeFile('/www/server/panel/class/monitorModel/common_process.json', json.dumps(data))
|
|
return public.returnMsg(True, "进程添加成功")
|
|
except:
|
|
return public.returnMsg(False, "进程添加失败")
|
|
|
|
def universal(self, get):
|
|
method = {
|
|
"题目1": "遇到未知进程解决办法。",
|
|
"1.1": "观察进程可执行目录和运行目录,是否与BT、项目名、常用软件相关,若与项目或者系统相关的进程且占用资源不大可不管。",
|
|
"1.2": "去‘百度’上搜索进程名,查看进程的归属,以及是否有害。ps:https://www.baidu.com",
|
|
"1.3": "咨询项目开发人员,看此进程是否由部署的项目所创建,若是,可加入到常见进程列表中。",
|
|
"1.4": "实在判断不了进程的性质,可到宝塔论坛发帖求助.ps:https://www.bt.cn/bbs/portal.php",
|
|
"1.5": "对进程做出详细的判断后,无用且占用资源较高,可关闭该进程。",
|
|
"1.6": "若占用资源较多的是使用当中的软件或项目,则可以尝试适当的优化,比如mysql优化、适当限制php的并发等。",
|
|
"题目2": "内存,cpu使用率不高,但负载很高解决办法",
|
|
"2.1": "负载高低还与线程数量、IO使用率、服务器本身有联系,可查看线程数量以及磁盘使用情况进行综合判断",
|
|
"2.2": "若本身服务器的配置较低,可以适当的考虑升级服务器配置",
|
|
"2.3": "若是遭受到网络攻击,也可导致服务器的负载偏高,可以开启宝塔防火墙以及安全插件进行防护。",
|
|
"2.4": "若服务器使用的是云服务器,也可能是服务器商家限制,可以咨询一下服务器商家的客服。"
|
|
}
|
|
return method
|