|
|
|
# coding:utf-8
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import io
|
|
|
|
import os
|
|
|
|
import time
|
|
|
|
import re
|
|
|
|
import threading
|
|
|
|
import psutil
|
|
|
|
import json
|
|
|
|
|
|
|
|
from typing import List, Dict
|
|
|
|
|
|
|
|
sys.path.append(os.getcwd() + "/class/core")
|
|
|
|
import mw
|
|
|
|
|
|
|
|
app_debug = False
|
|
|
|
if mw.isAppleSystem():
|
|
|
|
app_debug = True
|
|
|
|
|
|
|
|
|
|
|
|
def getPluginName():
|
|
|
|
return 'task_manager'
|
|
|
|
|
|
|
|
|
|
|
|
def getPluginDir():
|
|
|
|
return mw.getPluginDir() + '/' + getPluginName()
|
|
|
|
|
|
|
|
|
|
|
|
def getServerDir():
|
|
|
|
return mw.getServerDir() + '/' + getPluginName()
|
|
|
|
|
|
|
|
|
|
|
|
class mainClass(object):
|
|
|
|
|
|
|
|
pids = None
|
|
|
|
|
|
|
|
new_info = {}
|
|
|
|
old_info = {}
|
|
|
|
new_net_info = {}
|
|
|
|
old_net_info = {}
|
|
|
|
old_path = '/www/server/task_manager/task_old.json'
|
|
|
|
old_net_path = '/www/server/task_manager/network_old.json'
|
|
|
|
panel_pid = None
|
|
|
|
task_pid = None
|
|
|
|
__process_net_list = {}
|
|
|
|
__cpu_time = None
|
|
|
|
|
|
|
|
meter_head = {}
|
|
|
|
|
|
|
|
last_net_process = None
|
|
|
|
last_net_process_time = 0
|
|
|
|
|
|
|
|
# lock
|
|
|
|
_instance_lock = threading.Lock()
|
|
|
|
is_mac = False
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
# print("__init__")
|
|
|
|
self.is_mac = mw.isAppleSystem()
|
|
|
|
self.old_path = getServerDir()+'/task_old.json'
|
|
|
|
self.old_net_path = getServerDir()+'/network_old.json'
|
|
|
|
|
|
|
|
self.old_info['cpu_time'] = self.get_cpu_time()
|
|
|
|
self.old_info['time'] = time.time()
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def instance(cls, *args, **kwargs):
|
|
|
|
if not hasattr(mainClass, "_instance"):
|
|
|
|
with mainClass._instance_lock:
|
|
|
|
if not hasattr(mainClass, "_instance"):
|
|
|
|
mainClass._instance = mainClass(*args, **kwargs)
|
|
|
|
return mainClass._instance
|
|
|
|
|
|
|
|
def get_old(self):
|
|
|
|
if self.old_info: return True
|
|
|
|
# if not os.path.exists(self.old_path): return False
|
|
|
|
data = cache.get(self.old_path)
|
|
|
|
if not data: return False
|
|
|
|
# data = json.loads(data)
|
|
|
|
if not data: return False
|
|
|
|
self.old_info = data
|
|
|
|
del (data)
|
|
|
|
return True
|
|
|
|
|
|
|
|
def get_net_old(self):
|
|
|
|
if self.old_net_info: return True
|
|
|
|
# if not os.path.exists(self.old_net_path): return False
|
|
|
|
data = cache.get(self.old_net_path)
|
|
|
|
if not data: return False
|
|
|
|
# data = json.loads(data)
|
|
|
|
if not data: return False
|
|
|
|
self.old_net_info = data
|
|
|
|
del (data)
|
|
|
|
return True
|
|
|
|
|
|
|
|
def get_process_net_list(self):
|
|
|
|
w_file = '/dev/shm/bt_net_process'
|
|
|
|
if not os.path.exists(w_file): return
|
|
|
|
self.last_net_process = cache.get('net_process')
|
|
|
|
self.last_net_process_time = cache.get('last_net_process')
|
|
|
|
net_process_body = public.readFile(w_file)
|
|
|
|
if not net_process_body: return
|
|
|
|
net_process = net_process_body.split('\n')
|
|
|
|
for np in net_process:
|
|
|
|
if not np: continue
|
|
|
|
tmp = {}
|
|
|
|
np_list = np.split()
|
|
|
|
if len(np_list) < 5: continue
|
|
|
|
tmp['pid'] = int(np_list[0])
|
|
|
|
tmp['down'] = int(np_list[1])
|
|
|
|
tmp['up'] = int(np_list[2])
|
|
|
|
tmp['down_package'] = int(np_list[3])
|
|
|
|
tmp['up_package'] = int(np_list[4])
|
|
|
|
self.__process_net_list[tmp['pid']] = tmp
|
|
|
|
cache.set('net_process', self.__process_net_list, 600)
|
|
|
|
cache.set('last_net_process', time.time(), 600)
|
|
|
|
|
|
|
|
# 获取进程连接数
|
|
|
|
def get_connects(self, pid):
|
|
|
|
connects = 0
|
|
|
|
try:
|
|
|
|
if pid == 1: return connects
|
|
|
|
tp = '/proc/' + str(pid) + '/fd/'
|
|
|
|
if not os.path.exists(tp): return connects
|
|
|
|
for d in os.listdir(tp):
|
|
|
|
fname = tp + d
|
|
|
|
if os.path.islink(fname):
|
|
|
|
l = os.readlink(fname)
|
|
|
|
if l.find('socket:') != -1: connects += 1
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return connects
|
|
|
|
|
|
|
|
# 获取进程io写
|
|
|
|
def get_io_write(self, pid, io_write):
|
|
|
|
disk_io_write = 0
|
|
|
|
if not self.old_info: self.old_info = {}
|
|
|
|
if not pid in self.old_info:
|
|
|
|
self.old_info[pid] = {}
|
|
|
|
self.old_info[pid]['io_write'] = io_write
|
|
|
|
return disk_io_write
|
|
|
|
|
|
|
|
if not 'io_write' in self.old_info[pid]:
|
|
|
|
self.old_info[pid]['io_write'] = io_write
|
|
|
|
return disk_io_write
|
|
|
|
|
|
|
|
io_end = (io_write - self.old_info[pid]['io_write'])
|
|
|
|
if io_end > 0:
|
|
|
|
disk_io_write = io_end / (time.time() - self.old_info['time'])
|
|
|
|
self.old_info[pid]['io_write'] = io_write
|
|
|
|
if disk_io_write > 0: return int(disk_io_write)
|
|
|
|
return 0
|
|
|
|
|
|
|
|
# 获取io读
|
|
|
|
def get_io_read(self, pid, io_read):
|
|
|
|
disk_io_read = 0
|
|
|
|
if not pid in self.old_info:
|
|
|
|
self.old_info[pid] = {}
|
|
|
|
self.old_info[pid]['io_read'] = io_read
|
|
|
|
return disk_io_read
|
|
|
|
|
|
|
|
if not 'io_read' in self.old_info[pid]:
|
|
|
|
self.old_info[pid]['io_read'] = io_read
|
|
|
|
return disk_io_read
|
|
|
|
|
|
|
|
io_end = (io_read - self.old_info[pid]['io_read'])
|
|
|
|
if io_end > 0:
|
|
|
|
disk_io_read = io_end / (time.time() - self.old_info['time'])
|
|
|
|
self.old_info[pid]['io_read'] = io_read
|
|
|
|
if disk_io_read > 0: return int(disk_io_read)
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def get_mem_info(self, get=None):
|
|
|
|
mem = psutil.virtual_memory()
|
|
|
|
if self.is_mac:
|
|
|
|
memInfo = {'memTotal': mem.total}
|
|
|
|
memInfo['memRealUsed'] = memInfo['memTotal'] * (mem.percent / 100)
|
|
|
|
return memInfo['memRealUsed']
|
|
|
|
|
|
|
|
memInfo = {'memTotal': mem.total, 'memFree': mem.free, 'memBuffers': mem.buffers, 'memCached': mem.cached}
|
|
|
|
memInfo['memRealUsed'] = memInfo['memTotal'] - memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached']
|
|
|
|
return memInfo['memRealUsed']
|
|
|
|
|
|
|
|
# 进程备注,name,pid,启动命令
|
|
|
|
def get_process_ps(self, name, pid, p_exe=None, p=None):
|
|
|
|
processPs = {
|
|
|
|
'irqbalance': '系统进程-优化系统性能服务',
|
|
|
|
'containerd': 'docker管理服务',
|
|
|
|
'qmgr': '系统进程-管理和控制邮件进程',
|
|
|
|
'pickup': '系统进程-接收和处理待发送的邮件',
|
|
|
|
'cleanup': '系统进程-服务器释放资源进程',
|
|
|
|
'trivial-rewrite': '系统进程-邮件重写和转发服务',
|
|
|
|
'bt-ipfilter': '宝塔网络的IP过滤器',
|
|
|
|
'oneav': '微步木马检测服务',
|
|
|
|
'rhsmcertd': '系统进程-验证系统的订阅状态服务',
|
|
|
|
'tamperuser': '宝塔-企业级防篡改服务',
|
|
|
|
'lvmetad': '系统进程-元数据守护进程',
|
|
|
|
'containerd-shim-runc-v2': 'docker容器管理服务',
|
|
|
|
'tuned': '系统进程-优化系统服务',
|
|
|
|
'chronyd': '系统进程-时间同步服务',
|
|
|
|
'auditd': '系统进程-系统安全日志记录服务',
|
|
|
|
'gssproxy': '系统进程-身份验证和授权服务',
|
|
|
|
'ossfs': '阿里云对象存储挂载服务',
|
|
|
|
'cosfs': '腾讯云对象存储挂载服务',
|
|
|
|
'obsfs': '华为云对象存储挂载服务',
|
|
|
|
's3fs': '对象存储挂载服务',
|
|
|
|
'bosfs': '百度云对象存储挂载服务',
|
|
|
|
'jsvc': 'tomcat服务',
|
|
|
|
'oneavd': '微步木马检测服务',
|
|
|
|
'btsync': '宝塔文件同步服务',
|
|
|
|
'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': "python项目",
|
|
|
|
"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邮件传送代理',
|
|
|
|
'bash': 'bash命令行进程',
|
|
|
|
'(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': '延迟进程'
|
|
|
|
}
|
|
|
|
if p_exe:
|
|
|
|
if name == 'php-fpm':
|
|
|
|
try:
|
|
|
|
php_version = '.'.join(p_exe.split('/')[-3])
|
|
|
|
return 'PHP' + php_version + '进程'
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
elif name == 'python':
|
|
|
|
p_exe_arr = p_exe.split('/')
|
|
|
|
if p_exe_arr[-1] in ['BT-Task', 'task.py']:
|
|
|
|
return '面板-后台任务进程'
|
|
|
|
elif p_exe_arr[-1] in ['BT-Panel', 'runserver.py']:
|
|
|
|
return '面板-主进程'
|
|
|
|
elif p_exe.find('process_network_total') != -1:
|
|
|
|
return '面板-进程网络监控'
|
|
|
|
if p:
|
|
|
|
cmdline = ' '.join(p.cmdline()).strip()
|
|
|
|
cmdline_arr = cmdline.split('/')
|
|
|
|
if cmdline.find('process_network_total') != -1:
|
|
|
|
return '进程网络监控'
|
|
|
|
if cmdline_arr[-1] in ['BT-Task', 'task.py']:
|
|
|
|
return '后台任务进程'
|
|
|
|
elif cmdline_arr[-1] in ['BT-Panel', 'runserver.py']:
|
|
|
|
return '主进程'
|
|
|
|
elif cmdline.find('process_network_total') != -1:
|
|
|
|
return '进程网络监控'
|
|
|
|
elif cmdline.find('tamper_proof_service') != -1:
|
|
|
|
return '网站防篡改'
|
|
|
|
elif cmdline.find('syssafe') != -1:
|
|
|
|
return '系统加固'
|
|
|
|
elif cmdline.find('opwaf') != -1:
|
|
|
|
return 'WAF防火墙'
|
|
|
|
elif cmdline.find('acme') != -1:
|
|
|
|
return 'SSL证书签发'
|
|
|
|
elif cmdline.find('psync') != -1:
|
|
|
|
return '面板一键迁移'
|
|
|
|
elif cmdline.find('/panel/plugin') != -1:
|
|
|
|
return '面板插件进程'
|
|
|
|
elif cmdline.find('/www/server/cron/') != -1:
|
|
|
|
return '面板计划任务'
|
|
|
|
elif name == 'nginx':
|
|
|
|
if p.username() == 'www':
|
|
|
|
return 'Nginx子进程'
|
|
|
|
else:
|
|
|
|
return 'Nginx主进程'
|
|
|
|
elif p_exe == '/usr/bin/bash':
|
|
|
|
cmdline = ' '.join(p.cmdline()).strip()
|
|
|
|
if cmdline.find('/www/server/cron/') != -1:
|
|
|
|
return '面板计划任务'
|
|
|
|
elif cmdline.find('/www/server/mdserver-web/plugins') != -1:
|
|
|
|
return '面板插件进程'
|
|
|
|
|
|
|
|
if name in processPs: return processPs[name]
|
|
|
|
if name == 'python':
|
|
|
|
if self.is_panel_process(pid): return 'MW面板'
|
|
|
|
|
|
|
|
if p_exe:
|
|
|
|
exe_keys = {
|
|
|
|
'/www/server/mdserver-web/plugins/': '面板插件',
|
|
|
|
'/www/server/cron/': '计划任务进程',
|
|
|
|
'pm2': 'PM2进程管理器',
|
|
|
|
'PM2': 'PM2进程管理器',
|
|
|
|
'nvm': 'NVM Node版本管理器',
|
|
|
|
'npm': 'NPM Node包管理器'
|
|
|
|
}
|
|
|
|
|
|
|
|
for k in exe_keys.keys():
|
|
|
|
if p_exe.find(k) != -1: return exe_keys[k]
|
|
|
|
if name.find(k) != -1: return exe_keys[k]
|
|
|
|
|
|
|
|
return name
|
|
|
|
|
|
|
|
def get_process_network(self, pid):
|
|
|
|
'''
|
|
|
|
@name 获取进程网络流量
|
|
|
|
@author hwliang<2021-09-13>
|
|
|
|
@param pid<int> 进程ID
|
|
|
|
@return tuple
|
|
|
|
'''
|
|
|
|
if not self.__process_net_list:
|
|
|
|
self.get_process_net_list()
|
|
|
|
if not self.last_net_process_time: return 0, 0, 0, 0
|
|
|
|
if not pid in self.__process_net_list: return 0, 0, 0, 0
|
|
|
|
|
|
|
|
if not pid in self.last_net_process:
|
|
|
|
return self.__process_net_list[pid]['up'], self.__process_net_list[pid]['up_package'], \
|
|
|
|
self.__process_net_list[pid]['down'], self.__process_net_list[pid]['down_package']
|
|
|
|
|
|
|
|
up = int((self.__process_net_list[pid]['up'] - self.last_net_process[pid]['up']) / (
|
|
|
|
time.time() - self.last_net_process_time))
|
|
|
|
down = int((self.__process_net_list[pid]['down'] - self.last_net_process[pid]['down']) / (
|
|
|
|
time.time() - self.last_net_process_time))
|
|
|
|
up_package = int((self.__process_net_list[pid]['up_package'] - self.last_net_process[pid]['up_package']) / (
|
|
|
|
time.time() - self.last_net_process_time))
|
|
|
|
down_package = int(
|
|
|
|
(self.__process_net_list[pid]['down_package'] - self.last_net_process[pid]['down_package']) / (
|
|
|
|
time.time() - self.last_net_process_time))
|
|
|
|
return up, up_package, down, down_package
|
|
|
|
|
|
|
|
def get_process_cpu_time(self, cpu_times):
|
|
|
|
cpu_time = 0.00
|
|
|
|
for s in cpu_times: cpu_time += s
|
|
|
|
return cpu_time
|
|
|
|
|
|
|
|
# 获取cpu使用率
|
|
|
|
def get_cpu_percent(self, pid, cpu_times, cpu_time):
|
|
|
|
percent = 0.00
|
|
|
|
process_cpu_time = self.get_process_cpu_time(cpu_times)
|
|
|
|
|
|
|
|
if not self.old_info: self.old_info = {}
|
|
|
|
if not pid in self.old_info:
|
|
|
|
self.old_info[pid] = {}
|
|
|
|
self.old_info[pid]['cpu_time'] = process_cpu_time
|
|
|
|
return percent
|
|
|
|
|
|
|
|
if cpu_time == self.old_info['cpu_time']:
|
|
|
|
return 0.00
|
|
|
|
|
|
|
|
percent = round(100.00 * (process_cpu_time - self.old_info[pid]['cpu_time']) / (cpu_time - self.old_info['cpu_time']), 2)
|
|
|
|
# self.old_info[pid]['cpu_time'] = process_cpu_time
|
|
|
|
|
|
|
|
if percent > 0: return percent
|
|
|
|
return 0.00
|
|
|
|
|
|
|
|
# 获取平均负载
|
|
|
|
def get_load_average(self):
|
|
|
|
c = os.getloadavg()
|
|
|
|
data = {}
|
|
|
|
data['1'] = round(float(c[0]), 3) # float(c[0])
|
|
|
|
data['5'] = round(float(c[1]), 3) # float(c[1])
|
|
|
|
data['15'] = round(float(c[2]), 3) # float(c[2])
|
|
|
|
return data
|
|
|
|
|
|
|
|
def get_meter_head(self, get=None):
|
|
|
|
meter_head_file = getServerDir()+'/meter_head.json'
|
|
|
|
if os.path.exists(meter_head_file):
|
|
|
|
self.meter_head = json.loads(mw.readFile(meter_head_file))
|
|
|
|
else:
|
|
|
|
self.meter_head = {
|
|
|
|
'name': True,
|
|
|
|
'pid': True,
|
|
|
|
'cpu_percent': True,
|
|
|
|
'down': True,
|
|
|
|
'up': True,
|
|
|
|
'status': True,
|
|
|
|
'threads': True,
|
|
|
|
'user': True,
|
|
|
|
'ps': True,
|
|
|
|
'memory_used': True,
|
|
|
|
'io_read_bytes': True,
|
|
|
|
'io_write_bytes': True,
|
|
|
|
'connects': True
|
|
|
|
}
|
|
|
|
mw.writeFile(meter_head_file, json.dumps(self.meter_head))
|
|
|
|
return self.meter_head
|
|
|
|
|
|
|
|
# 添加进程查找
|
|
|
|
def search_pro(self, data, search):
|
|
|
|
try:
|
|
|
|
ldata = []
|
|
|
|
for i in data:
|
|
|
|
if search in i['name'] or search in i['exe'] or search in i['ps'] or search in i[
|
|
|
|
'user'] or search in str(i['pid']) or search in i['status']:
|
|
|
|
ldata.append(i)
|
|
|
|
elif hasattr(i, 'children'):
|
|
|
|
for k in i['children']:
|
|
|
|
if search in k['name'] or search in k['exe'] or search in k['ps'] or search in k[
|
|
|
|
'user'] or search in str(k['pid']):
|
|
|
|
ldata.append(i)
|
|
|
|
return ldata
|
|
|
|
except:
|
|
|
|
print(mw.getTracebackInfo())
|
|
|
|
return data
|
|
|
|
|
|
|
|
def get_cpu_time(self):
|
|
|
|
cpu_times = psutil.cpu_times()
|
|
|
|
|
|
|
|
cpu_time = 0.00
|
|
|
|
for s in cpu_times: cpu_time += s
|
|
|
|
return cpu_time
|
|
|
|
# return s.user + s.system + s.nice + s.idle
|
|
|
|
|
|
|
|
# 获取python的路径
|
|
|
|
def get_python_bin(self):
|
|
|
|
mw_dir = mw.getServerDir() + '/mdserver-web'
|
|
|
|
bin_file = mw_dir + '/bin/python'
|
|
|
|
if os.path.exists(bin_file):
|
|
|
|
return bin_file
|
|
|
|
return '/usr/bin/python'
|
|
|
|
|
|
|
|
# 检查process_network_total.py是否运行
|
|
|
|
def check_process_net_total(self):
|
|
|
|
mw_dir = mw.getServerDir() + '/mdserver-web'
|
|
|
|
_pid_file = mw_dir+'/logs/process_network_total.pid'
|
|
|
|
if os.path.exists(_pid_file):
|
|
|
|
pid = public.readFile(_pid_file)
|
|
|
|
if os.path.exists('/proc/' + pid): return True
|
|
|
|
|
|
|
|
cmd_file = getServerDir()+'/process_network_total.py'
|
|
|
|
python_bin = self.get_python_bin()
|
|
|
|
_cmd = 'nohup {} {} 600 &> /tmp/net.log &'.format(python_bin, cmd_file)
|
|
|
|
mw.execShell(_cmd)
|
|
|
|
|
|
|
|
# 进程折叠,将子进程折叠到父进程下,并将使用资源累加。
|
|
|
|
def __pro_s_s(self, data: List) -> List:
|
|
|
|
"""
|
|
|
|
将子进程合并到父进程中
|
|
|
|
:param data:进程列表
|
|
|
|
:return:合并后的进程列表增加children字段
|
|
|
|
"""
|
|
|
|
data1 = []
|
|
|
|
children_set = {'childrens': []}
|
|
|
|
for i in data:
|
|
|
|
if i['pid'] > 30 and i['ppid'] == 1:
|
|
|
|
children = self.__get_children(i['pid'])
|
|
|
|
s4 = time.time()
|
|
|
|
if children != []: children_set[i['pid']] = children
|
|
|
|
children_set['childrens'] += children
|
|
|
|
for i in data:
|
|
|
|
if i['pid'] in children_set:
|
|
|
|
i['children'] = []
|
|
|
|
for j in data:
|
|
|
|
if j['pid'] in children_set[i['pid']]:
|
|
|
|
i['children'].append(j)
|
|
|
|
i['memory_used'] += j['memory_used']
|
|
|
|
i['cpu_percent'] = round(i['cpu_percent'] + j['cpu_percent'], 2)
|
|
|
|
i['connects'] += j['connects']
|
|
|
|
i['threads'] += j['threads']
|
|
|
|
|
|
|
|
if 'io_write_bytes' in j:
|
|
|
|
i['io_write_bytes'] += j['io_write_bytes']
|
|
|
|
if 'io_read_bytes' in j:
|
|
|
|
i['io_read_bytes'] += j['io_read_bytes']
|
|
|
|
if 'io_write_speed' in j:
|
|
|
|
i['io_write_speed'] += j['io_write_speed']
|
|
|
|
if 'io_read_speed' in j:
|
|
|
|
i['io_read_speed'] += j['io_read_speed']
|
|
|
|
|
|
|
|
if 'up' in j:
|
|
|
|
i['up'] += j['up']
|
|
|
|
if 'up_package' in j:
|
|
|
|
i['up_package'] += j['up_package']
|
|
|
|
|
|
|
|
if 'down' in j:
|
|
|
|
i['down'] += j['down']
|
|
|
|
if 'down_package' in j:
|
|
|
|
i['down_package'] += j['down_package']
|
|
|
|
data1.append(i)
|
|
|
|
elif i['pid'] not in children_set['childrens']:
|
|
|
|
data1.append(i)
|
|
|
|
return data1
|
|
|
|
|
|
|
|
def __get_children(self, pid: int) -> List:
|
|
|
|
try:
|
|
|
|
p = psutil.Process(pid) # pid为指定进程的进程号
|
|
|
|
psutil.process_iter()
|
|
|
|
children = p.children(recursive=True) # 获取指定进程的所有子进程
|
|
|
|
pids = []
|
|
|
|
for child in children:
|
|
|
|
pids.append(child.pid)
|
|
|
|
return pids
|
|
|
|
except:
|
|
|
|
return []
|
|
|
|
|
|
|
|
# 外部接口,结束进程,pid30以上
|
|
|
|
def kill_process(self, get):
|
|
|
|
pid = int(get['pid'])
|
|
|
|
if pid < 30: return mw.returnData(False, '不能结束系统关键进程!')
|
|
|
|
if not pid in psutil.pids(): return mw.returnData(False, '指定进程不存在!')
|
|
|
|
if not 'killall' in get:
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
if self.is_panel_process(pid): return mw.returnData(False, '不能结束面板服务进程')
|
|
|
|
p.kill()
|
|
|
|
return mw.returnData(True, '进程已结束')
|
|
|
|
return self.kill_process_all(pid)
|
|
|
|
|
|
|
|
# 是否为面板进程
|
|
|
|
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(mw.execShell("ps aux | grep 'python3 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
|
|
|
|
|
|
|
|
# 遍历结束pid的子进程 kill_process_all——>引用kill_process_lower
|
|
|
|
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
|
|
|
|
|
|
|
|
# 结束进程树 kill_process——>引用kill_process_all
|
|
|
|
def kill_process_all(self, pid):
|
|
|
|
# public.print_log(pid)
|
|
|
|
if pid < 30: return mw.returnData(True, '已结束此进程树!')
|
|
|
|
if self.is_panel_process(pid): return mw.returnData(False, '不能结束面板服务进程')
|
|
|
|
try:
|
|
|
|
if not pid in psutil.pids(): mw.returnData(True, '已结束此进程树!')
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
ppid = p.ppid()
|
|
|
|
name = p.name()
|
|
|
|
p.kill()
|
|
|
|
mw.execShell('pkill -9 ' + name)
|
|
|
|
if name.find('php-') != -1:
|
|
|
|
mw.execShell("rm -f /tmp/php-cgi-*.sock")
|
|
|
|
elif name.find('mysql') != -1:
|
|
|
|
mw.execShell("rm -f /tmp/mysql.sock")
|
|
|
|
elif name.find('nginx') != -1:
|
|
|
|
mw.execShell("rm -f /tmp/mysql.sock")
|
|
|
|
self.kill_process_lower(pid)
|
|
|
|
if ppid: return self.kill_process_all(ppid)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
return public.returnMsg(True, '已结束此进程树!')
|
|
|
|
|
|
|
|
def get_process_list(self, args = {}):
|
|
|
|
# https://hellowac.github.io/psutil-doc-zh/processes/process_class/oneshot.html
|
|
|
|
if self.is_mac:
|
|
|
|
return self.get_process_list_mac(args)
|
|
|
|
return self.get_process_list_linux(args)
|
|
|
|
|
|
|
|
def get_process_list_mac(self, args = {}):
|
|
|
|
self.new_info['cpu_time'] = self.get_cpu_time()
|
|
|
|
self.new_info['time'] = time.time()
|
|
|
|
|
|
|
|
sortx = 'all'
|
|
|
|
if 'sortx' in args: sortx = args['sortx']
|
|
|
|
|
|
|
|
if not 'sortx' in args:
|
|
|
|
args['sortx'] = 'status'
|
|
|
|
if args['sortx'] == 'status': res = False
|
|
|
|
if 'reverse' in args:
|
|
|
|
if args['reverse'] in ['undefined', 'null']:
|
|
|
|
args['reverse'] = 'True'
|
|
|
|
args['sortx'] = 'all'
|
|
|
|
if not args['reverse'] in ['True', 'False']: args['reverse'] = 'True'
|
|
|
|
res_list = {'True': True, 'False': False}
|
|
|
|
res = res_list[args['reverse']]
|
|
|
|
else:
|
|
|
|
args['reverse'] = True
|
|
|
|
if args['reverse'] in ['undefined', 'null']:
|
|
|
|
args['reverse'] = 'True'
|
|
|
|
args['sortx'] = 'all'
|
|
|
|
|
|
|
|
info = {}
|
|
|
|
info['activity'] = 0
|
|
|
|
info['cpu'] = 0.00
|
|
|
|
info['mem'] = 0
|
|
|
|
info['disk'] = 0
|
|
|
|
status_ps = {'sleeping': '睡眠', 'running': '活动'}
|
|
|
|
ppids = psutil.pids()
|
|
|
|
processList = []
|
|
|
|
for pid in ppids:
|
|
|
|
tmp = {}
|
|
|
|
try:
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
with p.oneshot():
|
|
|
|
p_state = p.status()
|
|
|
|
try:
|
|
|
|
tmp['exe'] = p.exe()
|
|
|
|
except Exception as e:
|
|
|
|
continue
|
|
|
|
|
|
|
|
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['connects'] = self.get_connects(pid)
|
|
|
|
|
|
|
|
if p_state == 'running': info['activity'] += 1
|
|
|
|
if p_state in status_ps: p_state = status_ps[p_state]
|
|
|
|
|
|
|
|
try:
|
|
|
|
tmp['threads'] = p.num_threads()
|
|
|
|
except Exception as e:
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
tmp['ps'] = self.get_process_ps(tmp['name'], pid, tmp['exe'], p)
|
|
|
|
tmp['up'], tmp['up_package'], tmp['down'], tmp['down_package'] = self.get_process_network(pid)
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
p_cpus = p.cpu_times()
|
|
|
|
except Exception as e:
|
|
|
|
continue
|
|
|
|
|
|
|
|
try:
|
|
|
|
p_mem = p.memory_info()
|
|
|
|
except Exception as e:
|
|
|
|
continue
|
|
|
|
if p_mem.rss == 0: continue
|
|
|
|
|
|
|
|
tmp['memory_used'] = p_mem.rss
|
|
|
|
tmp['cpu_percent'] = self.get_cpu_percent(str(pid), p_cpus, self.new_info['cpu_time'])
|
|
|
|
# print(tmp['cpu_percent'])
|
|
|
|
if tmp['cpu_percent'] > 100: tmp['cpu_percent'] = 0.1
|
|
|
|
info['cpu'] += tmp['cpu_percent']
|
|
|
|
info['disk'] += 0
|
|
|
|
|
|
|
|
processList.append(tmp)
|
|
|
|
del (p)
|
|
|
|
del (tmp)
|
|
|
|
except Exception as e:
|
|
|
|
print("err:", mw.getTracebackInfo())
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
processList = self.__pro_s_s(processList)
|
|
|
|
res = True
|
|
|
|
|
|
|
|
if args['sortx'] not in ['all']:
|
|
|
|
processList = sorted(processList, key=lambda x: x[args['sortx']], reverse=res)
|
|
|
|
else:
|
|
|
|
processList = sorted(processList, key=lambda x: [x['cpu_percent'], x['connects'], x['threads'],
|
|
|
|
x['memory_used']], reverse=res)
|
|
|
|
|
|
|
|
info['load_average'] = self.get_load_average()
|
|
|
|
data = {}
|
|
|
|
data['is_mac'] = self.is_mac
|
|
|
|
data['process_list'] = processList
|
|
|
|
info['cpu'] = round(info['cpu'], 3)
|
|
|
|
info['mem'] = self.get_mem_info()
|
|
|
|
data['info'] = info
|
|
|
|
if hasattr(args, 'search'):
|
|
|
|
if args.search != '':
|
|
|
|
data['process_list'] = self.search_pro(data['process_list'], args.search)
|
|
|
|
self.get_meter_head()
|
|
|
|
data['meter_head'] = self.meter_head
|
|
|
|
|
|
|
|
data['meter_head']['io_read_bytes'] = False
|
|
|
|
data['meter_head']['io_write_bytes'] = False
|
|
|
|
data['meter_head']['down'] = False
|
|
|
|
data['meter_head']['up'] = False
|
|
|
|
return data
|
|
|
|
|
|
|
|
# 获取进程信息
|
|
|
|
def get_process_list_linux(self, get = {}):
|
|
|
|
self.check_process_net_total()
|
|
|
|
self.pids = psutil.pids()
|
|
|
|
processList = []
|
|
|
|
if type(self.new_info) != dict: self.new_info = {}
|
|
|
|
self.new_info['cpu_time'] = self.get_cpu_time()
|
|
|
|
self.new_info['time'] = time.time()
|
|
|
|
self.get_process_net_list()
|
|
|
|
|
|
|
|
|
|
|
|
if not 'sortx' in get:
|
|
|
|
get['sortx'] = 'all'
|
|
|
|
|
|
|
|
res = True
|
|
|
|
if get['sortx'] == 'status':
|
|
|
|
res = False
|
|
|
|
|
|
|
|
if 'reverse' in get:
|
|
|
|
if get['reverse'] in ['undefined', 'null']:
|
|
|
|
get['reverse'] = 'True'
|
|
|
|
get['sortx'] = 'all'
|
|
|
|
if not get['reverse'] in ['True', 'False']: get['reverse'] = 'True'
|
|
|
|
res_list = {'True': True, 'False': False}
|
|
|
|
res = res_list[get['reverse']]
|
|
|
|
else:
|
|
|
|
get['reverse'] = True
|
|
|
|
if get['reverse'] in ['undefined', 'null']:
|
|
|
|
get['reverse'] = 'True'
|
|
|
|
get['sortx'] = 'all'
|
|
|
|
|
|
|
|
info = {}
|
|
|
|
info['activity'] = 0
|
|
|
|
info['cpu'] = 0.00
|
|
|
|
info['mem'] = 0
|
|
|
|
info['disk'] = 0
|
|
|
|
status_ps = {'sleeping': '睡眠', 'running': '活动'}
|
|
|
|
for pid in self.pids:
|
|
|
|
tmp = {}
|
|
|
|
try:
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
with p.oneshot():
|
|
|
|
p_mem = p.memory_full_info()
|
|
|
|
if p_mem.rss == 0: continue
|
|
|
|
pio = p.io_counters()
|
|
|
|
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]
|
|
|
|
tmp['exe'] = p.exe()
|
|
|
|
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['memory_used'] = p_mem.uss
|
|
|
|
tmp['cpu_percent'] = self.get_cpu_percent(str(pid), p_cpus, self.new_info['cpu_time'])
|
|
|
|
if tmp['name'] == 'BT-Panel' and tmp['cpu_percent'] > 1:
|
|
|
|
tmp['cpu_percent'] = round(tmp['cpu_percent'] % 1, 2)
|
|
|
|
tmp['io_write_bytes'] = pio.write_bytes
|
|
|
|
tmp['io_read_bytes'] = pio.read_bytes
|
|
|
|
tmp['io_write_speed'] = self.get_io_write(str(pid), pio.write_bytes)
|
|
|
|
tmp['io_read_speed'] = self.get_io_read(str(pid), pio.read_bytes)
|
|
|
|
tmp['connects'] = self.get_connects(pid)
|
|
|
|
tmp['threads'] = p.num_threads()
|
|
|
|
tmp['ps'] = self.get_process_ps(tmp['name'], pid, tmp['exe'], p)
|
|
|
|
tmp['up'], tmp['up_package'], tmp['down'], tmp['down_package'] = self.get_process_network(pid)
|
|
|
|
if tmp['cpu_percent'] > 100: tmp['cpu_percent'] = 0.1
|
|
|
|
info['cpu'] += tmp['cpu_percent']
|
|
|
|
info['disk'] += tmp['io_write_speed'] + tmp['io_read_speed']
|
|
|
|
processList.append(tmp)
|
|
|
|
del (p)
|
|
|
|
del (tmp)
|
|
|
|
except Exception as e:
|
|
|
|
print(mw.getTracebackInfo())
|
|
|
|
continue
|
|
|
|
|
|
|
|
processList = self.__pro_s_s(processList)
|
|
|
|
|
|
|
|
if get['sortx'] not in ['all']:
|
|
|
|
processList = sorted(processList, key=lambda x: x[get['sortx']], reverse=res)
|
|
|
|
else:
|
|
|
|
processList = sorted(processList, key=lambda x: [x['cpu_percent'], x['up'], x['down'], x['io_write_speed'],
|
|
|
|
x['io_read_speed'], x['connects'], x['threads'],
|
|
|
|
x['memory_used']], reverse=res)
|
|
|
|
info['load_average'] = self.get_load_average()
|
|
|
|
data = {}
|
|
|
|
data['process_list'] = processList
|
|
|
|
info['cpu'] = round(info['cpu'], 2)
|
|
|
|
info['mem'] = self.get_mem_info()
|
|
|
|
data['info'] = info
|
|
|
|
if 'search' in get:
|
|
|
|
if get['search'] != '':
|
|
|
|
data['process_list'] = self.search_pro(data['process_list'], get['search'])
|
|
|
|
self.get_meter_head()
|
|
|
|
data['meter_head'] = self.meter_head
|
|
|
|
return data
|
|
|
|
|
|
|
|
def object_to_dict(self, obj):
|
|
|
|
result = {}
|
|
|
|
for name in dir(obj):
|
|
|
|
value = getattr(obj, name)
|
|
|
|
if not name.startswith('__') and not callable(value) and not name.startswith('_'): result[name] = value
|
|
|
|
return result
|
|
|
|
|
|
|
|
def list_to_dict(self, data):
|
|
|
|
result = []
|
|
|
|
for s in data:
|
|
|
|
result.append(self.object_to_dict(s))
|
|
|
|
return result
|
|
|
|
|
|
|
|
# 获取进程的详细信息
|
|
|
|
def get_process_info(self, args={}):
|
|
|
|
pid = int(args['pid'])
|
|
|
|
try:
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
processInfo = {}
|
|
|
|
|
|
|
|
if self.is_mac:
|
|
|
|
p_mem = self.object_to_dict(p.memory_info())
|
|
|
|
else:
|
|
|
|
p_mem = self.object_to_dict(p.memory_full_info())
|
|
|
|
pio = p.io_counters()
|
|
|
|
processInfo['io_write_bytes'] = pio.write_bytes;
|
|
|
|
processInfo['io_read_bytes'] = pio.read_bytes;
|
|
|
|
# p_cpus= p.cpu_times()
|
|
|
|
processInfo['exe'] = p.exe()
|
|
|
|
processInfo['name'] = p.name();
|
|
|
|
processInfo['pid'] = pid;
|
|
|
|
processInfo['ppid'] = p.ppid()
|
|
|
|
processInfo['pname'] = 'sys'
|
|
|
|
if processInfo['ppid'] != 0: processInfo['pname'] = psutil.Process(processInfo['ppid']).name()
|
|
|
|
processInfo['comline'] = p.cmdline()
|
|
|
|
processInfo['create_time'] = int(p.create_time())
|
|
|
|
processInfo['open_files'] = self.list_to_dict(p.open_files())
|
|
|
|
processInfo['status'] = p.status();
|
|
|
|
processInfo['user'] = p.username();
|
|
|
|
processInfo['memory_full'] = p_mem
|
|
|
|
|
|
|
|
processInfo['connects'] = self.get_connects(pid)
|
|
|
|
processInfo['threads'] = p.num_threads()
|
|
|
|
processInfo['ps'] = self.get_process_ps(processInfo['name'], pid, processInfo['exe'], p)
|
|
|
|
except Exception as e:
|
|
|
|
# print(mw.getTracebackInfo())
|
|
|
|
return mw.returnData(False, '指定进程已关闭!')
|
|
|
|
return processInfo
|
|
|
|
|
|
|
|
# 获取用户组处理函数 get_user_list——>引用get_group_name
|
|
|
|
def get_group_name(self, gid):
|
|
|
|
for g in self.groupList:
|
|
|
|
if g['gid'] == gid: return g['group']
|
|
|
|
return ''
|
|
|
|
|
|
|
|
# 用户名注释:ps get_user_list——>引用get_user_ps
|
|
|
|
def get_user_ps(self, name, ps):
|
|
|
|
userPs = {'www': '面板', 'root': '超级管理员', 'mysql': '用于运行MySQL的用户',
|
|
|
|
'mongo': '用于运行MongoDB的用户',
|
|
|
|
'git': 'git用户', 'mail': 'mail', 'nginx': '第三方nginx用户', 'postfix': 'postfix邮局用户',
|
|
|
|
'lp': '打印服务帐号',
|
|
|
|
'daemon': '控制后台进程的系统帐号', 'nobody': '匿名帐户', 'bin': '管理大部分命令的帐号',
|
|
|
|
'adm': '管理某些管理文件的帐号', 'smtp': 'smtp邮件'}
|
|
|
|
if name in userPs: return userPs[name]
|
|
|
|
if not ps: return name
|
|
|
|
return ps
|
|
|
|
|
|
|
|
# 获取服务器的组名和id,从/etc/group中读取。存储到self.groupList,get_user_list——>引用get_group_list
|
|
|
|
def get_group_list(self, get):
|
|
|
|
tmpList = mw.readFile('/etc/group').split("\n")
|
|
|
|
groupList = []
|
|
|
|
for gl in tmpList:
|
|
|
|
tmp = gl.split(':')
|
|
|
|
if len(tmp) < 3: continue
|
|
|
|
groupInfo = {}
|
|
|
|
groupInfo['group'] = tmp[0]
|
|
|
|
groupInfo['gid'] = tmp[2]
|
|
|
|
groupList.append(groupInfo)
|
|
|
|
return groupList;
|
|
|
|
|
|
|
|
# 外部接口,删除用户,不能删除系统运行环境用户
|
|
|
|
def remove_user(self, get):
|
|
|
|
if self.is_mac:
|
|
|
|
return mw.returnData(False, '无法操作!')
|
|
|
|
users = ['www', 'root', 'mysql', 'shutdown', 'postfix', 'smmsp', 'sshd', 'systemd-network', 'systemd-bus-proxy',
|
|
|
|
'avahi-autoipd', 'mail', 'sync', 'lp', 'adm', 'bin', 'mailnull', 'ntp', 'daemon', 'sys'];
|
|
|
|
|
|
|
|
if 'user' in get:
|
|
|
|
return mw.returnData(False, '缺少参数!')
|
|
|
|
|
|
|
|
if get['user'] in users: return mw.returnData(False, '不能删除系统和环境关键用户!')
|
|
|
|
|
|
|
|
r = mw.execShell("userdel " + get['user'])
|
|
|
|
if r[1].find('process') != -1:
|
|
|
|
try:
|
|
|
|
pid = r[1].split()[-1]
|
|
|
|
p = psutil.Process(int(pid))
|
|
|
|
pname = p.name()
|
|
|
|
p.kill()
|
|
|
|
mw.execShell("pkill -9 " + pname)
|
|
|
|
r = mw.execShell("userdel " + get.user)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
if r[1].find('userdel:') != -1: return mw.returnData(False, r[1]);
|
|
|
|
return mw.returnData(True, '删除成功!')
|
|
|
|
|
|
|
|
# 获取用户列表 从/etc/passwd文件中读取
|
|
|
|
def get_user_list(self, get={}):
|
|
|
|
tmpList = mw.readFile('/etc/passwd').strip().split("\n")
|
|
|
|
userList = []
|
|
|
|
self.groupList = self.get_group_list(get)
|
|
|
|
for ul in tmpList:
|
|
|
|
tmp = ul.split(':')
|
|
|
|
if len(tmp) < 6: continue
|
|
|
|
userInfo = {}
|
|
|
|
userInfo['username'] = tmp[0]
|
|
|
|
userInfo['uid'] = tmp[2]
|
|
|
|
userInfo['gid'] = tmp[3]
|
|
|
|
userInfo['group'] = self.get_group_name(tmp[3])
|
|
|
|
userInfo['ps'] = self.get_user_ps(tmp[0], tmp[4])
|
|
|
|
userInfo['home'] = tmp[5]
|
|
|
|
userInfo['login_shell'] = tmp[6]
|
|
|
|
userList.append(userInfo)
|
|
|
|
|
|
|
|
# print(userList)
|
|
|
|
if 'search' in get:
|
|
|
|
if get['search'] != '':
|
|
|
|
userList = self.search_user(userList, get['search'])
|
|
|
|
return userList
|
|
|
|
|
|
|
|
# get_network_list ——>引用get_network
|
|
|
|
def get_network(self):
|
|
|
|
try:
|
|
|
|
self.get_net_old()
|
|
|
|
networkIo = psutil.net_io_counters()[:4]
|
|
|
|
self.new_net_info['upTotal'] = networkIo[0]
|
|
|
|
self.new_net_info['downTotal'] = networkIo[1]
|
|
|
|
self.new_net_info['upPackets'] = networkIo[2]
|
|
|
|
self.new_net_info['downPackets'] = networkIo[3]
|
|
|
|
self.new_net_info['time'] = time.time()
|
|
|
|
|
|
|
|
if not self.old_net_info: self.old_net_info = {}
|
|
|
|
if not 'upTotal' in self.old_net_info:
|
|
|
|
time.sleep(0.1)
|
|
|
|
networkIo = psutil.net_io_counters()[:4]
|
|
|
|
self.old_net_info['upTotal'] = networkIo[0]
|
|
|
|
self.old_net_info['downTotal'] = networkIo[1]
|
|
|
|
self.old_net_info['upPackets'] = networkIo[2]
|
|
|
|
self.old_net_info['downPackets'] = networkIo[3]
|
|
|
|
self.old_net_info['time'] = time.time()
|
|
|
|
|
|
|
|
s = self.new_net_info['time'] - self.old_net_info['time']
|
|
|
|
networkInfo = {}
|
|
|
|
networkInfo['upTotal'] = networkIo[0]
|
|
|
|
networkInfo['downTotal'] = networkIo[1]
|
|
|
|
networkInfo['up'] = round((float(networkIo[0]) - self.old_net_info['upTotal']) / s, 2)
|
|
|
|
networkInfo['down'] = round((float(networkIo[1]) - self.old_net_info['downTotal']) / s, 2)
|
|
|
|
networkInfo['downPackets'] = networkIo[3]
|
|
|
|
networkInfo['upPackets'] = networkIo[2]
|
|
|
|
networkInfo['downPackets_s'] = int((networkIo[3] - self.old_net_info['downPackets']) / s)
|
|
|
|
networkInfo['upPackets_s'] = int((networkIo[2] - self.old_net_info['upPackets']) / s)
|
|
|
|
cache.set(self.old_net_path, self.new_net_info, 600)
|
|
|
|
return networkInfo
|
|
|
|
except:
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
# 获取当前网络连接信息
|
|
|
|
def get_network_list(self, get = {}):
|
|
|
|
data = {}
|
|
|
|
data['is_mac'] = False
|
|
|
|
if self.is_mac:
|
|
|
|
data['is_mac'] = self.is_mac
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
netstats = psutil.net_connections()
|
|
|
|
|
|
|
|
networkList = []
|
|
|
|
for netstat in netstats:
|
|
|
|
tmp = {}
|
|
|
|
if netstat.type == 1:
|
|
|
|
tmp['type'] = 'tcp'
|
|
|
|
else:
|
|
|
|
tmp['type'] = 'udp'
|
|
|
|
tmp['family'] = netstat.family
|
|
|
|
tmp['laddr'] = netstat.laddr
|
|
|
|
tmp['raddr'] = netstat.raddr
|
|
|
|
tmp['status'] = netstat.status
|
|
|
|
p = psutil.Process(netstat.pid)
|
|
|
|
tmp['process'] = p.name()
|
|
|
|
if tmp['process'] in ['BT-Panel', 'gunicorn', 'baota_coll', 'baota_client']: continue
|
|
|
|
tmp['pid'] = netstat.pid
|
|
|
|
networkList.append(tmp)
|
|
|
|
del (p)
|
|
|
|
del (tmp)
|
|
|
|
networkList = sorted(networkList, key=lambda x: x['status'], reverse=True)
|
|
|
|
|
|
|
|
data['list'] = networkList
|
|
|
|
data['state'] = self.get_network()
|
|
|
|
if hasattr(get, 'search'):
|
|
|
|
if get.search != '':
|
|
|
|
data['list'] = self.search_network(data['list'], get.search)
|
|
|
|
return data
|
|
|
|
|
|
|
|
# 获取当前运行级别 get_service_list ——> 引用get_my_runlevel
|
|
|
|
def get_my_runlevel(self):
|
|
|
|
try:
|
|
|
|
runlevel = mw.execShell('runlevel')[0].split()[1]
|
|
|
|
except:
|
|
|
|
runlevel_dict = {"multi-user.target": '3', 'rescue.target': '1', 'poweroff.target': '0',
|
|
|
|
'graphical.target': '5', "reboot.target": '6'}
|
|
|
|
r_tmp = mw.execShell('systemctl get-default')[0].strip()
|
|
|
|
if r_tmp in runlevel_dict:
|
|
|
|
runlevel = runlevel_dict[r_tmp]
|
|
|
|
else:
|
|
|
|
runlevel = '3'
|
|
|
|
return runlevel
|
|
|
|
|
|
|
|
# 服务注释 get_service_list——>引用 get_run_ps
|
|
|
|
def get_run_ps(self, name):
|
|
|
|
runPs = {'netconsole': '网络控制台日志', 'network': '网络服务', 'jexec': 'JAVA', 'tomcat8': 'Apache Tomcat',
|
|
|
|
'tomcat7': 'Apache Tomcat', 'mariadb': 'Mariadb',
|
|
|
|
'tomcat9': 'Apache Tomcat', 'tomcat': 'Apache Tomcat', 'memcached': 'Memcached缓存器',
|
|
|
|
'php-fpm-53': 'PHP-5.3', 'php-fpm-52': 'PHP-5.2',
|
|
|
|
'php-fpm-54': 'PHP-5.4', 'php-fpm-55': 'PHP-5.5', 'php-fpm-56': 'PHP-5.6', 'php-fpm-70': 'PHP-7.0',
|
|
|
|
'php-fpm-71': 'PHP-7.1',
|
|
|
|
'php-fpm-72': 'PHP-7.2', 'rsync_inotify': 'rsync实时同步', 'pure-ftpd': 'FTP服务',
|
|
|
|
'mongodb': 'MongoDB', 'nginx': 'Web服务器(Nginx)',
|
|
|
|
'httpd': 'Web服务器(Apache)', 'mw': '面板', 'mysqld': 'MySQL数据库', 'rsynd': 'rsync主服务',
|
|
|
|
'php-fpm': 'PHP服务', 'systemd': '系统核心服务',
|
|
|
|
'/etc/rc.local': '用户自定义启动脚本', '/etc/profile': '全局用户环境变量',
|
|
|
|
'/etc/inittab': '用于自定义系统运行级别', '/etc/rc.sysinit': '系统初始化时调用的脚本',
|
|
|
|
'sshd': 'SSH服务', 'crond': '计划任务服务', 'udev-post': '设备管理系统', 'auditd': '审核守护进程',
|
|
|
|
'rsyslog': 'rsyslog服务', 'sendmail': '邮件发送服务', 'blk-availability': 'lvm2相关',
|
|
|
|
'local': '用户自定义启动脚本', 'netfs': '网络文件系统', 'lvm2-monitor': 'lvm2相关',
|
|
|
|
'xensystem': 'xen云平台相关', 'iptables': 'iptables防火墙', 'ip6tables': 'iptables防火墙 for IPv6',
|
|
|
|
'firewalld': 'firewall防火墙'}
|
|
|
|
if name in runPs: return runPs[name]
|
|
|
|
return name
|
|
|
|
|
|
|
|
# 清除注释
|
|
|
|
def clear_comments(self, body):
|
|
|
|
bodyTmp = body.split("\n")
|
|
|
|
bodyR = ""
|
|
|
|
for tmp in bodyTmp:
|
|
|
|
if tmp.startswith('#'): continue
|
|
|
|
if tmp.strip() == '': continue
|
|
|
|
bodyR += tmp
|
|
|
|
return bodyR
|
|
|
|
|
|
|
|
# 获取启动项
|
|
|
|
def get_run_list(self, get={}):
|
|
|
|
data = {}
|
|
|
|
data['is_mac'] = False
|
|
|
|
if self.is_mac:
|
|
|
|
data['is_mac'] = self.is_mac
|
|
|
|
return data
|
|
|
|
|
|
|
|
runFile = ['/etc/rc.local', '/etc/profile', '/etc/inittab', '/etc/rc.sysinit']
|
|
|
|
runList = []
|
|
|
|
for rfile in runFile:
|
|
|
|
if not os.path.exists(rfile): continue
|
|
|
|
bodyR = self.clear_comments(mw.readFile(rfile))
|
|
|
|
if not bodyR: continue
|
|
|
|
stat = os.stat(rfile)
|
|
|
|
accept = str(oct(stat.st_mode)[-3:])
|
|
|
|
if accept == '644': continue
|
|
|
|
tmp = {}
|
|
|
|
tmp['name'] = rfile
|
|
|
|
tmp['srcfile'] = rfile
|
|
|
|
tmp['size'] = os.path.getsize(rfile)
|
|
|
|
tmp['access'] = accept
|
|
|
|
tmp['ps'] = self.get_run_ps(rfile)
|
|
|
|
# tmp['body'] = bodyR
|
|
|
|
runList.append(tmp)
|
|
|
|
runlevel = self.get_my_runlevel()
|
|
|
|
runPath = ['/etc/init.d', '/etc/rc' + runlevel + '.d']
|
|
|
|
tmpAll = []
|
|
|
|
islevel = False
|
|
|
|
for rpath in runPath:
|
|
|
|
if not os.path.exists(rpath): continue
|
|
|
|
if runPath[1] == rpath: islevel = True
|
|
|
|
for f in os.listdir(rpath):
|
|
|
|
if f[:1] != 'S': continue
|
|
|
|
filename = rpath + '/' + f
|
|
|
|
if not os.path.exists(filename): continue
|
|
|
|
if os.path.isdir(filename): continue
|
|
|
|
if os.path.islink(filename):
|
|
|
|
flink = os.readlink(filename).replace('../', '/etc/')
|
|
|
|
if not os.path.exists(flink): continue
|
|
|
|
filename = flink
|
|
|
|
tmp = {}
|
|
|
|
tmp['name'] = f
|
|
|
|
if islevel: tmp['name'] = f[3:]
|
|
|
|
if tmp['name'] in tmpAll: continue
|
|
|
|
stat = os.stat(filename)
|
|
|
|
accept = str(oct(stat.st_mode)[-3:])
|
|
|
|
if accept == '644': continue
|
|
|
|
tmp['srcfile'] = filename
|
|
|
|
tmp['access'] = accept
|
|
|
|
tmp['size'] = os.path.getsize(filename)
|
|
|
|
tmp['ps'] = self.get_run_ps(tmp['name'])
|
|
|
|
runList.append(tmp)
|
|
|
|
tmpAll.append(tmp['name'])
|
|
|
|
data = {}
|
|
|
|
data['run_list'] = runList
|
|
|
|
data['run_level'] = runlevel
|
|
|
|
if 'search' in get:
|
|
|
|
if get['search'] != '':
|
|
|
|
data['run_list'] = self.search_run(data['run_list'], get['search'])
|
|
|
|
return data
|
|
|
|
|
|
|
|
# 检查服务是否为系统服务get_systemctl_list——>引用cont_systemctl
|
|
|
|
def cont_systemctl(self, name):
|
|
|
|
conts = ['systemd', 'rhel', 'plymouth', 'rc-', '@', 'init', 'ipr', 'dbus', '-local']
|
|
|
|
for c in conts:
|
|
|
|
if name.find(c) != -1: return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
# 获取系统服务运行级别 get_service_list——>引用get_systemctl_list
|
|
|
|
def get_systemctl_list(self, serviceList, runlevel):
|
|
|
|
systemctl_user_path = '/usr/lib/systemd/system/'
|
|
|
|
systemctl_run_path = '/etc/systemd/system/multi-user.target.wants/'
|
|
|
|
if not os.path.exists(systemctl_user_path) or not os.path.exists(systemctl_run_path): return serviceList
|
|
|
|
r = '.service'
|
|
|
|
for d in os.listdir(systemctl_user_path):
|
|
|
|
if d.find(r) == -1: continue;
|
|
|
|
if not self.cont_systemctl(d): continue;
|
|
|
|
isrun = '<span style="color:red;" title="点击开启">关闭</span>'
|
|
|
|
serviceInfo = {}
|
|
|
|
serviceInfo['name'] = d.replace(r, '')
|
|
|
|
serviceInfo['runlevel_0'] = isrun
|
|
|
|
serviceInfo['runlevel_1'] = isrun
|
|
|
|
serviceInfo['runlevel_2'] = isrun
|
|
|
|
serviceInfo['runlevel_3'] = isrun
|
|
|
|
serviceInfo['runlevel_4'] = isrun
|
|
|
|
serviceInfo['runlevel_5'] = isrun
|
|
|
|
serviceInfo['runlevel_6'] = isrun
|
|
|
|
if os.path.exists(systemctl_run_path + d):
|
|
|
|
isrun = '<span style="color:green;" title="点击关闭">开启</span>'
|
|
|
|
serviceInfo['runlevel_' + runlevel] = isrun
|
|
|
|
serviceInfo['runlevel_3'] = isrun
|
|
|
|
serviceInfo['runlevel_5'] = isrun
|
|
|
|
|
|
|
|
serviceInfo['ps'] = self.get_run_ps(serviceInfo['name'])
|
|
|
|
serviceList.append(serviceInfo)
|
|
|
|
return serviceList
|
|
|
|
|
|
|
|
# 外部接口,删除服务。不能删除mw
|
|
|
|
def remove_service(self, get):
|
|
|
|
if not 'serviceName' in get:
|
|
|
|
return mw.returnData(False,'缺少参数');
|
|
|
|
|
|
|
|
serviceName = get['serviceName']
|
|
|
|
if serviceName == 'mw': return mw.returnData(False, '不能通过面板结束面板服务!')
|
|
|
|
systemctl_user_path = '/usr/lib/systemd/system/'
|
|
|
|
if os.path.exists(systemctl_user_path + serviceName + '.service'):
|
|
|
|
return mw.returnData(False,'Systemctl托管的服务不能通过面板删除');
|
|
|
|
|
|
|
|
mw.execShell('service ' + serviceName + ' stop')
|
|
|
|
if os.path.exists('/usr/sbin/update-rc.d'):
|
|
|
|
mw.execShell('update-rc.d ' + serviceName + ' remove')
|
|
|
|
elif os.path.exists('/usr/sbin/chkconfig'):
|
|
|
|
mw.execShell('chkconfig --del ' + serviceName)
|
|
|
|
else:
|
|
|
|
mw.execShell("rm -f /etc/rc0.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc1.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc2.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc3.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc4.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc5.d/*" + serviceName)
|
|
|
|
mw.execShell("rm -f /etc/rc6.d/*" + serviceName)
|
|
|
|
filename = '/etc/init.d/' + serviceName
|
|
|
|
if os.path.exists(filename): os.remove(filename)
|
|
|
|
return mw.returnData(True, '删除成功!')
|
|
|
|
|
|
|
|
# 外部接口,设置软件运行环境,不能设置0,6
|
|
|
|
def set_runlevel_state(self, get):
|
|
|
|
if not 'runlevel' in get:
|
|
|
|
return mw.returnData(False,'缺少参数[runlevel]')
|
|
|
|
|
|
|
|
if not 'serviceName' in get:
|
|
|
|
return mw.returnData(False,'缺少参数[serviceName]')
|
|
|
|
|
|
|
|
runlevel = get['runlevel']
|
|
|
|
serviceName = get['serviceName']
|
|
|
|
if runlevel == '0' or runlevel == '6':
|
|
|
|
return mw.returnData(False,'为安全考虑,不能通过面板直接修改此运行级别')
|
|
|
|
|
|
|
|
systemctl_user_path = '/usr/lib/systemd/system/'
|
|
|
|
systemctl_run_path = '/etc/systemd/system/multi-user.target.wants/'
|
|
|
|
if os.path.exists(systemctl_user_path + serviceName + '.service'):
|
|
|
|
runlevel_cmd = mw.execShell('runlevel')[0].split()[1]
|
|
|
|
if runlevel_cmd != runlevel:
|
|
|
|
return mw.returnData(False,'Systemctl托管的服务不能设置非当前运行级别的状态')
|
|
|
|
action = 'enable'
|
|
|
|
if os.path.exists(systemctl_run_path + serviceName + '.service'):
|
|
|
|
action = 'disable'
|
|
|
|
mw.execShell('systemctl ' + action + ' ' + serviceName + '.service')
|
|
|
|
return mw.returnData(True, '设置成功!')
|
|
|
|
|
|
|
|
rc_d = '/etc/rc' + runlevel + '.d/'
|
|
|
|
import shutil
|
|
|
|
for d in os.listdir(rc_d):
|
|
|
|
if d[3:] != serviceName: continue
|
|
|
|
sfile = rc_d + d
|
|
|
|
c = 'S'
|
|
|
|
if d[:1] == 'S': c = 'K'
|
|
|
|
dfile = rc_d + c + d[1:]
|
|
|
|
shutil.move(sfile, dfile)
|
|
|
|
return mw.returnData(True, '设置成功!')
|
|
|
|
return mw.returnData(False, '设置失败!')
|
|
|
|
|
|
|
|
|
|
|
|
# 外部接口 查询服务启动级别 /etc/init.d/
|
|
|
|
def get_service_list(self, get = {}):
|
|
|
|
data = {}
|
|
|
|
data['is_mac'] = False
|
|
|
|
if self.is_mac:
|
|
|
|
data['is_mac'] = self.is_mac
|
|
|
|
return data
|
|
|
|
|
|
|
|
init_d = '/etc/init.d/'
|
|
|
|
serviceList = []
|
|
|
|
for sname in os.listdir(init_d):
|
|
|
|
try:
|
|
|
|
if str(oct(os.stat(init_d + sname).st_mode)[-3:]) == '644': continue
|
|
|
|
serviceInfo = {}
|
|
|
|
runlevels = self.get_runlevel(sname)
|
|
|
|
serviceInfo['name'] = sname
|
|
|
|
serviceInfo['runlevel_0'] = runlevels[0]
|
|
|
|
serviceInfo['runlevel_1'] = runlevels[1]
|
|
|
|
serviceInfo['runlevel_2'] = runlevels[2]
|
|
|
|
serviceInfo['runlevel_3'] = runlevels[3]
|
|
|
|
serviceInfo['runlevel_4'] = runlevels[4]
|
|
|
|
serviceInfo['runlevel_5'] = runlevels[5]
|
|
|
|
serviceInfo['runlevel_6'] = runlevels[6]
|
|
|
|
serviceInfo['ps'] = self.get_run_ps(sname)
|
|
|
|
serviceList.append(serviceInfo)
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
|
|
|
|
data['runlevel'] = self.get_my_runlevel()
|
|
|
|
data['serviceList'] = sorted(serviceList, key=lambda x: x['name'], reverse=False)
|
|
|
|
data['serviceList'] = self.get_systemctl_list(data['serviceList'], data['runlevel'])
|
|
|
|
if 'search' in get:
|
|
|
|
if get['search'] != '':
|
|
|
|
data['serviceList'] = self.search_service(data['serviceList'], get['search'])
|
|
|
|
return data
|
|
|
|
|
|
|
|
def search_service(self, data, search):
|
|
|
|
try:
|
|
|
|
ldata = []
|
|
|
|
for i in data:
|
|
|
|
if search in i['name'] or search in i['ps']:
|
|
|
|
ldata.append(i)
|
|
|
|
return ldata
|
|
|
|
except:
|
|
|
|
return data
|
|
|
|
|
|
|
|
# 获取存放计划任务的路径
|
|
|
|
def get_cron_file(self):
|
|
|
|
filename = '/var/spool/cron/crontabs/root'
|
|
|
|
if os.path.exists(filename): return filename
|
|
|
|
filename = '/var/spool/cron/root'
|
|
|
|
if not os.path.exists(filename):
|
|
|
|
mw.writeFile(filename, "")
|
|
|
|
return filename
|
|
|
|
|
|
|
|
# 外部接口,获取计划任务列表
|
|
|
|
def get_cron_list(self, get = {}):
|
|
|
|
filename = self.get_cron_file()
|
|
|
|
tmpList = public.readFile(filename).split("\n")
|
|
|
|
cronList = []
|
|
|
|
for c in tmpList:
|
|
|
|
c = c.strip()
|
|
|
|
if c.startswith('#'): continue
|
|
|
|
tmp = c.split(' ')
|
|
|
|
if len(tmp) < 6: continue
|
|
|
|
cronInfo = {}
|
|
|
|
cronInfo['cycle'] = self.decode_cron_cycle(tmp)
|
|
|
|
if not cronInfo['cycle']: continue
|
|
|
|
ctmp = self.decode_cron_connand(tmp)
|
|
|
|
cronInfo['command'] = c
|
|
|
|
cronInfo['ps'] = ctmp[1]
|
|
|
|
cronInfo['exe'] = ctmp[2]
|
|
|
|
cronInfo['test'] = ctmp[0]
|
|
|
|
cronList.append(cronInfo)
|
|
|
|
if hasattr(get, 'search'):
|
|
|
|
if get.search != '':
|
|
|
|
cronList = self.search_cron(cronList, get.search)
|
|
|
|
return cronList
|
|
|
|
|
|
|
|
# 外部接口 强制结束会话
|
|
|
|
def pkill_session(self, get= {}):
|
|
|
|
if not 'pts' in get:
|
|
|
|
return mw.returnData(False, '缺少参数!')
|
|
|
|
mw.execShell("pkill -kill -t " + get['pts'])
|
|
|
|
return mw.returnData(True, '已强行结束会话[' + get['pts'] + ']')
|
|
|
|
|
|
|
|
# 获取当前会话
|
|
|
|
def get_who(self, get = {}):
|
|
|
|
whoTmp = mw.execShell('who')[0]
|
|
|
|
tmpList = whoTmp.split("\n")
|
|
|
|
whoList = []
|
|
|
|
for w in tmpList:
|
|
|
|
tmp = w.split()
|
|
|
|
if len(tmp) < 5: continue
|
|
|
|
whoInfo = {}
|
|
|
|
whoInfo['user'] = tmp[0]
|
|
|
|
whoInfo['pts'] = tmp[1]
|
|
|
|
whoInfo['date'] = tmp[2] + ' ' + tmp[3]
|
|
|
|
whoInfo['ip'] = tmp[4].replace('(', '').replace(')', '')
|
|
|
|
if len(tmp) > 5:
|
|
|
|
whoInfo['date'] = tmp[2] + ' ' + tmp[3] + ' ' + tmp[4]
|
|
|
|
whoInfo['ip'] = tmp[5].replace('(', '').replace(')', '')
|
|
|
|
whoList.append(whoInfo)
|
|
|
|
if hasattr(get, 'search'):
|
|
|
|
if get.search != '':
|
|
|
|
whoList = self.search_who(whoList, get.search)
|
|
|
|
return whoList
|
|
|
|
|
|
|
|
def test_cpu(self):
|
|
|
|
pid = 43046
|
|
|
|
p = psutil.Process(pid)
|
|
|
|
tmp = {}
|
|
|
|
self.new_info['cpu_time'] = self.get_cpu_time()
|
|
|
|
self.new_info['time'] = time.time()
|
|
|
|
with p.oneshot():
|
|
|
|
p_cpus = p.cpu_times()
|
|
|
|
print(p_cpus)
|
|
|
|
|
|
|
|
tmp['cpu_percent'] = self.get_cpu_percent(str(pid), p_cpus, self.new_info['cpu_time'])
|
|
|
|
print(tmp['cpu_percent'])
|
|
|
|
|
|
|
|
|
|
|
|
mc_instance = mainClass.instance()
|
|
|
|
|
|
|
|
def get_network_list(args = {}):
|
|
|
|
return mc_instance.get_network_list(args)
|
|
|
|
|
|
|
|
def get_process_list(args = {}):
|
|
|
|
return mc_instance.get_process_list(args)
|
|
|
|
|
|
|
|
def kill_process(args = {}):
|
|
|
|
return mc_instance.kill_process(args)
|
|
|
|
|
|
|
|
def kill_process_all(args = {}):
|
|
|
|
if not 'pid' in args:
|
|
|
|
return mw.returnData(False, '缺少参数!')
|
|
|
|
return mc_instance.kill_process_all(int(args['pid']))
|
|
|
|
|
|
|
|
def remove_service(args = {}):
|
|
|
|
return mc_instance.remove_service(args)
|
|
|
|
|
|
|
|
def set_runlevel_state(args = {}):
|
|
|
|
return mc_instance.set_runlevel_state(args)
|
|
|
|
|
|
|
|
def get_service_list(args = {}):
|
|
|
|
return mc_instance.get_service_list(args)
|
|
|
|
|
|
|
|
def get_run_list(args = {}):
|
|
|
|
return mc_instance.get_run_list(args)
|
|
|
|
|
|
|
|
def get_cron_list(args = {}):
|
|
|
|
return mc_instance.get_cron_list(args)
|
|
|
|
|
|
|
|
def pkill_session(args = {}):
|
|
|
|
return mc_instance.pkill_session(args)
|
|
|
|
|
|
|
|
def get_who(args = {}):
|
|
|
|
return mc_instance.get_who(args)
|
|
|
|
|
|
|
|
def get_process_info(args = {}):
|
|
|
|
return mc_instance.get_process_info(args)
|
|
|
|
|
|
|
|
def get_user_list(args = {}):
|
|
|
|
return mc_instance.get_user_list(args)
|
|
|
|
|
|
|
|
def remove_user(args = {}):
|
|
|
|
return mc_instance.remove_user(args)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
print(mc_instance.get_process_list())
|
|
|
|
# print(mc_instance.get_process_info({'pid':66647}))
|
|
|
|
# for x in range(10):
|
|
|
|
# mc_instance.test_cpu()
|
|
|
|
# time.sleep(1)
|
|
|
|
|
|
|
|
# mc_instance.test_cpu()
|
|
|
|
# time.sleep(1)
|
|
|
|
# mc_instance.test_cpu()
|