mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 01:39:25 +08:00
update
This commit is contained in:
@@ -180,4 +180,3 @@ plugins/frp
|
||||
plugins/file_search
|
||||
plugins/proxysql
|
||||
plugins/tidb
|
||||
plugins/task_manager
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 455 B |
Executable
+554
@@ -0,0 +1,554 @@
|
||||
<style>
|
||||
/*任务管理器*/
|
||||
.man-menu-sub {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.t-mana .table > tbody > tr.active td {
|
||||
background-color: #E4EEE0;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
}
|
||||
|
||||
.search-bar .search_input {
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #ccc;
|
||||
outline: none;
|
||||
padding-left: 8px;
|
||||
vertical-align: top;
|
||||
width: 230px;
|
||||
}
|
||||
|
||||
.search-bar .search_input:focus {
|
||||
border-color: #20a53a;
|
||||
|
||||
span.glyphicon-search {
|
||||
color: #20a53a;
|
||||
}
|
||||
}
|
||||
|
||||
.search-bar .glyphicon {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
display: inline-block;
|
||||
font-family: 'Glyphicons Halflings';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 1;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.search-bar .glyphicon-search {
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 10px;
|
||||
color: #888;
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
top: 11px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.r56 {
|
||||
right: 56px !important;
|
||||
}
|
||||
|
||||
.man-menu-sub {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.man-menu-sub span {
|
||||
padding: 14px 15px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.man-menu-sub .on {
|
||||
border-bottom: 2px solid #20a53a;
|
||||
color: #20a53a;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.soft-ico-min {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.soft-ico-min img {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.table-cont {
|
||||
height: 500px;
|
||||
overflow: auto;
|
||||
border: #ddd 1px solid;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ts-line {
|
||||
position: absolute;
|
||||
top: 99px;
|
||||
height: 1px;
|
||||
background-color: #ddd;
|
||||
left: 16px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.t-mana .bt-ico-ask {
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
line-height: 14px;
|
||||
}
|
||||
|
||||
.mini-info {
|
||||
width: 100%;
|
||||
border-top: #DBDBEA 1px solid;
|
||||
background-color: #f6f6f6;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.mini-info-box {
|
||||
width: 500px;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
border: #DBDBEA 1px solid;
|
||||
border-radius: 6px;
|
||||
height: 66px;
|
||||
box-shadow: 0 0 40px #eee;
|
||||
}
|
||||
|
||||
.mini-info-con {
|
||||
float: left;
|
||||
height: 100%;
|
||||
width: 33%;
|
||||
line-height: 26px;
|
||||
padding: 6px 16px;
|
||||
}
|
||||
|
||||
.mini-info-con:nth-of-type(2) {
|
||||
border-left: #DBDBEA 1px solid;
|
||||
border-right: #DBDBEA 1px solid;
|
||||
width: 34%;
|
||||
}
|
||||
|
||||
.mini-info-con p {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mini-info-con .tname {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.mini-level {
|
||||
border: #ddd 1px solid;
|
||||
width: 166px;
|
||||
background-color: #fff;
|
||||
border-radius: 6px;
|
||||
margin: 0 auto;
|
||||
height: 66px;
|
||||
line-height: 66px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.jc-detail .tname {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.jc-detail h3.tname {
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.jc-detail .jc-info {
|
||||
margin: 10px 0;
|
||||
border-bottom: #ddd 1px solid;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#TaskManagement .td-pid {
|
||||
/* display: flex; */
|
||||
/* border-top: #ddd 2px solid; */
|
||||
/* height: 38px; */
|
||||
/* height: 100%; */
|
||||
/* margin-top: 1px; */
|
||||
}
|
||||
|
||||
.td-pid img {
|
||||
/* margin-right: 8px; */
|
||||
/* display: inline-block; */
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
/* position: relative;
|
||||
left: -80px;
|
||||
filter: drop-shadow(#fff 80px 0); */
|
||||
/* position: relative;
|
||||
left: -80px;
|
||||
filter: drop-shadow(#238B37 0 80px); */
|
||||
}
|
||||
|
||||
.td-pid svg {
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.td-pid .colp {
|
||||
transform: rotate(-90deg);
|
||||
-moz-transform: rotate(-90deg);
|
||||
-webkit-transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.td-pid .arrow:hover {
|
||||
filter: drop-shadow(#999999 0 0)
|
||||
}
|
||||
|
||||
.td-pid .process-child {
|
||||
margin-left: 50px;
|
||||
/* display: none; */
|
||||
}
|
||||
|
||||
.td-pid span {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.td-pid a {
|
||||
display: block;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
#TaskManagement th: {
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
#TaskManagement tr: {
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
#TaskManagement tr:hover {
|
||||
/* background-color: rgb(245, 247, 250,0.6); */
|
||||
background-color: rgb(246, 246, 246, 0.65);
|
||||
}
|
||||
|
||||
#TaskManagement .process-select {
|
||||
/* background-color: rgb(242, 242, 242); */
|
||||
/* background-color: rgb(245, 247, 250,0.6); */
|
||||
background-color: rgb(246, 246, 246, 0.6);
|
||||
/* background-color: rgb(246, 246, 246,0.65); */
|
||||
}
|
||||
|
||||
#taskResourceTable .process-select {
|
||||
/* background-color: rgb(242, 242, 242); */
|
||||
background-color: #F1F9F3;
|
||||
}
|
||||
|
||||
#TaskManagement .process-select:hover {
|
||||
/* background-color: rgb(211, 210, 210); */
|
||||
/* background-color: rgb(245, 247, 250); */
|
||||
background-color: rgb(246, 246, 246);
|
||||
/* border: 1px solid #ddd;
|
||||
box-sizing: border-box; */
|
||||
}
|
||||
|
||||
#taskResourceTable .process-select:hover {
|
||||
/* background-color: rgb(211, 210, 210); */
|
||||
background-color: #BCE4C4;
|
||||
}
|
||||
|
||||
.resource-panel {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 700px;
|
||||
/* height: 300px; */
|
||||
}
|
||||
|
||||
.resource-tab {
|
||||
float: left;
|
||||
width: 100px;
|
||||
height: 300px;
|
||||
background-color: thistle;
|
||||
}
|
||||
|
||||
.resource-right {
|
||||
margin-left: 100px;
|
||||
/* width: 100%; */
|
||||
/* background-color: gray; */
|
||||
/* height: 600px; */
|
||||
}
|
||||
|
||||
.resource-panel-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.divtable-hide {
|
||||
display: none;
|
||||
/* visibility: hidden; */
|
||||
}
|
||||
|
||||
.resource-tab span {
|
||||
display: block;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.resource-tab span:hover {
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.plug_menu {
|
||||
display: none;
|
||||
}
|
||||
.plug_menu .setting_ul::after{
|
||||
display: none;
|
||||
}
|
||||
.plug_menu .setting_ul.undisplay::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
font-size: 14px;
|
||||
top: -7px;
|
||||
right: 8px;
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
transform: rotate(-45deg);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.25);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.set_list_fid_dropdown {
|
||||
display: inline-block;
|
||||
line-height: 30px;
|
||||
margin-left: 10px;
|
||||
position: relative;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.set_list_fid_dropdown .setting_btn {
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.set_list_fid_dropdown .setting_btn:hover{
|
||||
background: #e9f6eb;
|
||||
border-color: #bce4c4;
|
||||
}
|
||||
.set_list_fid_dropdown .icon-setting {
|
||||
color: rgb(102, 102, 102);
|
||||
}
|
||||
.set_list_fid_dropdown .setting_btn:hover .icon-setting {
|
||||
color: #20a53a;
|
||||
}
|
||||
.set_list_fid_dropdown .setting_ul {
|
||||
position: absolute;
|
||||
z-index: 99;
|
||||
background: #fff;
|
||||
width: 150px;
|
||||
right: 0;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25);
|
||||
padding: 10px 0;
|
||||
margin-top: 10px;
|
||||
display: none;
|
||||
}
|
||||
.set_list_fid_dropdown .setting_ul::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
font-size: 14px;
|
||||
top: -7px;
|
||||
right: 8px;
|
||||
display: inline-block;
|
||||
background: #fff;
|
||||
transform: rotate(-45deg);
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.25);
|
||||
border-right: 1px solid rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
.setting_ul .setting_ul_li{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 27px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.setting_ul .setting_ul_li:hover{
|
||||
background: #e9f6eb;
|
||||
}
|
||||
.setting_ul .setting_ul_li.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.setting_ul .setting_ul_li i {
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border: 1px solid #ccc;
|
||||
background-color: #fff;
|
||||
vertical-align: top;
|
||||
position: relative;
|
||||
border-radius: 2px;
|
||||
}
|
||||
.setting_ul .setting_ul_li.active i {
|
||||
background-color: #20a53a;
|
||||
border-color: #20a53a;
|
||||
}
|
||||
.setting_ul .setting_ul_li.disabled i {
|
||||
background-color: #edf2fc;
|
||||
border-color: #dcdfe6;
|
||||
}
|
||||
.setting_ul .setting_ul_li.active.disabled i {
|
||||
background-color: #f2f6fc;
|
||||
border-color: #dcdfe6;
|
||||
}
|
||||
.setting_ul .setting_ul_li.active.disabled i::after{
|
||||
border: solid #dcdfe6;
|
||||
border-width: 0 2px 2px 0;
|
||||
}
|
||||
.setting_ul .setting_ul_li.active i::after{
|
||||
content: '';
|
||||
position: absolute;
|
||||
display: block;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-left: -2px;
|
||||
margin-top: -6px;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
border: solid #fff;
|
||||
border-width: 0 2px 2px 0;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="t-mana TaskManView">
|
||||
<div class="man-menu-sub mlr15">
|
||||
<div>
|
||||
<span class="p_list on">进程</span>
|
||||
<!-- <span class="p_resource">资源</span> -->
|
||||
<span class="p_run">启动项</span>
|
||||
<span class="p_service">服务</span>
|
||||
<span class="p_network">网络</span>
|
||||
<span class="p_user">用户</span>
|
||||
<span class="p_cron">计划任务</span>
|
||||
<span class="p_session">会话</span>
|
||||
</div>
|
||||
<div style="display: flex;flex-direction: row;align-items: center;justify-content: flex-end;">
|
||||
<div class="search-bar ">
|
||||
<input type="text" class="search_input " style="" placeholder="支持名称、字段模糊搜索">
|
||||
<span class="glyphicon glyphicon-search r56" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div class="table_config set_list_fid_dropdown" title="设置表头">
|
||||
<div class="setting_btn"><i class="glyphicon glyphicon-cog icon-setting"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ts-line"></div>
|
||||
|
||||
<div class="divtable taskdivtable pd15">
|
||||
<div id="table-cont" class="table-cont">
|
||||
<table id="TaskManagement" class="table table-hover" width="100%" style="border:none"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="resource-panel pd15">
|
||||
<div class="resource-tab">
|
||||
<span>CPU</span>
|
||||
<span>内存</span>
|
||||
<span>磁盘</span>
|
||||
</div>
|
||||
|
||||
<div class="resource-right">
|
||||
<div class="resource-top"></div>
|
||||
<div class="resource-middle divtable">
|
||||
<div id="table-cont" class="table-cont" style="height:100px;">
|
||||
<table id="taskResourceTable" class="table table-hover" width="100%" style="border:none">
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="resource-bottom"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mini-info" id="load_average"></div>
|
||||
<div class="plug_menu set_list_fid_dropdown">
|
||||
<ul class="setting_ul" style="display: none;">
|
||||
<li class="setting_ul_li ps active disabled" name="ps">
|
||||
<i></i><span class="ml10">应用名称</span>
|
||||
</li>
|
||||
<li class="setting_ul_li pid active disabled" name="pid">
|
||||
<i></i> <span class="ml10">PID</span>
|
||||
</li>
|
||||
<li class="setting_ul_li threads active" name="threads">
|
||||
<i></i> <span class="ml10">线程</span>
|
||||
</li>
|
||||
<li class="setting_ul_li user active" name="user">
|
||||
<i></i> <span class="ml10">用户</span>
|
||||
</li>
|
||||
<li class="setting_ul_li cpu_percent active disabled" name="cpu_percent">
|
||||
<i></i> <span class="ml10">CPU</span>
|
||||
</li>
|
||||
<li class="setting_ul_li memory_used active disabled" name="memory_used">
|
||||
<i></i> <span class="ml10">内存</span>
|
||||
</li>
|
||||
<li class="setting_ul_li io_read_bytes active" name="io_read_bytes">
|
||||
<i></i> <span class="ml10">io读</span>
|
||||
</li>
|
||||
<li class="setting_ul_li io_write_bytes active" name="io_write_bytes">
|
||||
<i></i> <span class="ml10">io写</span>
|
||||
</li>
|
||||
<li class="setting_ul_li up active" name="up">
|
||||
<i></i> <span class="ml10">上行</span>
|
||||
</li>
|
||||
<li class="setting_ul_li down active" name="down">
|
||||
<i></i> <span class="ml10">下行</span>
|
||||
</li>
|
||||
<li class="setting_ul_li connects active" name="connects">
|
||||
<i></i> <span class="ml10">连接</span>
|
||||
</li>
|
||||
<li class="setting_ul_li status active" name="status">
|
||||
<i></i> <span class="ml10">状态</span>
|
||||
</li>
|
||||
<li class="setting_ul_li active disabled" name="">
|
||||
<i></i> <span class="ml10">操作</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
$('.layui-layer-page').css({'width': '1000px'});
|
||||
$.getScript( "/plugins/file?name=task_manager&f=js/task_manager.js", function(){
|
||||
console.log("load js ok!");
|
||||
});
|
||||
</script>
|
||||
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
|
||||
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()
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
def status():
|
||||
return 'start'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "轻松管理进程、流量监控、启动项、用户、服务、计划任务、会话[<span style='color:red;'>开发中</span>]",
|
||||
"name": "task_manager",
|
||||
"title": "任务管理器",
|
||||
"shell": "install.sh",
|
||||
"versions":"1.0",
|
||||
"tip": "soft",
|
||||
"checks": "server/task_manager",
|
||||
"path": "server/task_manager",
|
||||
"display": 1,
|
||||
"author": "task_manager",
|
||||
"date": "2024-06-01",
|
||||
"home": "task_manager",
|
||||
"type": 0,
|
||||
"pid": "4"
|
||||
}
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/task_manager
|
||||
|
||||
echo "$VERSION" > $serverPath/task_manager/version.pl
|
||||
echo "安装任务管理器成功"
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/task_manager
|
||||
echo "卸载任务管理器成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,318 @@
|
||||
#coding: utf-8
|
||||
#-------------------------------------------------------------------
|
||||
# 宝塔Linux面板
|
||||
#-------------------------------------------------------------------
|
||||
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||||
#-------------------------------------------------------------------
|
||||
# Author: hwliang<hwl@bt.cn>
|
||||
#-------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import struct
|
||||
|
||||
os.chdir('/www/server/panel')
|
||||
if 'class/' in sys.path: sys.path.insert(0,"class/")
|
||||
import copy
|
||||
try:
|
||||
import pcap
|
||||
except ImportError:
|
||||
if os.path.exists('/usr/bin/apt'):
|
||||
os.system("apt install libpcap-dev -y")
|
||||
elif os.path.exists('/usr/bin/dnf'):
|
||||
red_file = '/etc/redhat-release'
|
||||
if os.path.exists(red_file):
|
||||
f = open(red_file,'r')
|
||||
red_body = f.read()
|
||||
f.close()
|
||||
if red_body.find('CentOS Linux release 8.') != -1:
|
||||
rpm_file = '/root/libpcap-1.9.1.rpm'
|
||||
down_url = "wget -O {} https://repo.almalinux.org/almalinux/8/PowerTools/x86_64/os/Packages/libpcap-devel-1.9.1-5.el8.x86_64.rpm --no-check-certificate -T 10".format(rpm_file)
|
||||
print(down_url)
|
||||
os.system(down_url)
|
||||
os.system("rpm -ivh {}".format(rpm_file))
|
||||
if os.path.exists(rpm_file): os.remove(rpm_file)
|
||||
else:
|
||||
os.system("dnf install libpcap-devel -y")
|
||||
else:
|
||||
os.system("dnf install libpcap-devel -y")
|
||||
elif os.path.exists('/usr/bin/yum'):
|
||||
os.system("yum install libpcap-devel -y")
|
||||
|
||||
os.system("btpip install pypcap")
|
||||
try:
|
||||
import pcap
|
||||
except ImportError:
|
||||
print("pypcap module install failed.")
|
||||
sys.exit()
|
||||
|
||||
class process_network_total:
|
||||
__pid_file = 'logs/process_network_total.pid'
|
||||
__inode_list = {}
|
||||
__net_process_list = {}
|
||||
__net_process_size = {}
|
||||
__last_stat = 0
|
||||
__last_write_time = 0
|
||||
__end_time = 0
|
||||
|
||||
def start(self,timeout = 0):
|
||||
'''
|
||||
@name 启动进程网络监控
|
||||
@author hwliang<2021-09-13>
|
||||
@param timeout<int> 结束时间(秒),0表示持久运行,默认为0
|
||||
@return void
|
||||
'''
|
||||
stime = time.time()
|
||||
self.__end_time = timeout + stime
|
||||
self.__last_stat = stime
|
||||
try:
|
||||
p = pcap.pcap() # 监听所有网卡
|
||||
p.setfilter('tcp') # 只监听TCP数据包
|
||||
for p_time,p_data in p:
|
||||
self.handle_packet(p_data)
|
||||
# 过期停止监听
|
||||
if timeout > 0:
|
||||
if p_time > self.__end_time:
|
||||
self.rm_pid_file()
|
||||
break
|
||||
except:
|
||||
self.rm_pid_file()
|
||||
|
||||
def handle_packet(self, pcap_data):
|
||||
'''
|
||||
@name 处理pcap数据包
|
||||
@author hwliang<2021-09-12>
|
||||
@param pcap_data<bytes> pcap数据包
|
||||
@return void
|
||||
'''
|
||||
# 获取IP协议头
|
||||
ip_header = pcap_data[14:34]
|
||||
# 解析src/dst地址
|
||||
src_ip = ip_header[12:16]
|
||||
dst_ip = ip_header[16:20]
|
||||
# 解析sport/dport端口
|
||||
src_port = pcap_data[34:36]
|
||||
dst_port = pcap_data[36:38]
|
||||
|
||||
src = src_ip + b':' + src_port
|
||||
dst = dst_ip + b':' + dst_port
|
||||
# 计算数据包长度
|
||||
pack_size = len(pcap_data)
|
||||
# 统计进程流量
|
||||
self.total_net_process(dst,src,pack_size)
|
||||
|
||||
def total_net_process(self,dst,src,pack_size):
|
||||
'''
|
||||
@name 统计进程流量
|
||||
@author hwliang<2021-09-13>
|
||||
@param dst<bytes> 目标地址
|
||||
@param src<bytes> 源地址
|
||||
@param pack_size<int> 数据包长度
|
||||
@return void
|
||||
'''
|
||||
self.get_tcp_stat()
|
||||
direction = None
|
||||
mtime = time.time()
|
||||
if dst in self.__net_process_list:
|
||||
pid = self.__net_process_list[dst]
|
||||
direction = 'down'
|
||||
elif src in self.__net_process_list:
|
||||
pid = self.__net_process_list[src]
|
||||
direction = 'up'
|
||||
else:
|
||||
if mtime - self.__last_stat > 3:
|
||||
self.__last_stat = mtime
|
||||
self.get_tcp_stat(True)
|
||||
if dst in self.__net_process_list:
|
||||
pid = self.__net_process_list[dst]
|
||||
direction = 'down'
|
||||
elif src in self.__net_process_list:
|
||||
pid = self.__net_process_list[src]
|
||||
direction = 'up'
|
||||
|
||||
if not direction: return False
|
||||
if not pid: return False
|
||||
if not pid in self.__net_process_size:
|
||||
self.__net_process_size[pid] = {}
|
||||
self.__net_process_size[pid]['down'] = 0
|
||||
self.__net_process_size[pid]['up'] = 0
|
||||
self.__net_process_size[pid]['up_package'] = 0
|
||||
self.__net_process_size[pid]['down_package'] = 0
|
||||
|
||||
self.__net_process_size[pid][direction] += pack_size
|
||||
self.__net_process_size[pid][direction + '_package'] += 1
|
||||
|
||||
# 写入到文件
|
||||
if mtime - self.__last_write_time > 1:
|
||||
self.__last_write_time = mtime
|
||||
self.write_net_process()
|
||||
|
||||
def write_net_process(self):
|
||||
'''
|
||||
@name 写入进程流量
|
||||
@author hwliang<2021-09-13>
|
||||
@return void
|
||||
'''
|
||||
w_file = '/dev/shm/bt_net_process'
|
||||
process_size = copy.deepcopy(self.__net_process_size)
|
||||
net_process = []
|
||||
for pid in process_size.keys():
|
||||
net_process.append(str(pid) + " " + str(process_size[pid]['down']) + " " + str(process_size[pid]['up']) + " " + str(process_size[pid]['down_package']) + " " + str(process_size[pid]['up_package']))
|
||||
|
||||
f = open(w_file,'w+',encoding='utf-8')
|
||||
f.write('\n'.join(net_process))
|
||||
f.close()
|
||||
|
||||
def hex_to_ip(self, hex_ip):
|
||||
'''
|
||||
@name 将16进制的IP地址转换为字符串IP地址
|
||||
@author hwliang<2021-09-13>
|
||||
@param hex_ip<string> 16进制的IP地址:16进程端口
|
||||
@return tuple(ip<str>,port<int>) IP地址,端口
|
||||
'''
|
||||
hex_ip,hex_port = hex_ip.split(':')
|
||||
ip = '.'.join([str(int(hex_ip[i:i+2], 16)) for i in range(0, len(hex_ip), 2)][::-1])
|
||||
port = int(hex_port, 16)
|
||||
return ip,port
|
||||
|
||||
def get_tcp_stat(self,force = False):
|
||||
'''
|
||||
@name 获取当前TCP连接状态表
|
||||
@author hwliang<2021-09-13>
|
||||
@param force<bool> 是否强制刷新
|
||||
@return dict
|
||||
'''
|
||||
if not force and self.__net_process_list: return self.__net_process_list
|
||||
self.__net_process_list = {}
|
||||
tcp_stat_file = '/proc/net/tcp'
|
||||
tcp_stat = open(tcp_stat_file, 'rb')
|
||||
tcp_stat_list = tcp_stat.read().decode('utf-8').split('\n')
|
||||
tcp_stat.close()
|
||||
tcp_stat_list = tcp_stat_list[1:]
|
||||
if force: self.get_process_inodes(force)
|
||||
for i in tcp_stat_list:
|
||||
tcp_tmp = i.split()
|
||||
if len(tcp_tmp) < 10: continue
|
||||
inode = tcp_tmp[9]
|
||||
if inode == '0': continue
|
||||
local_ip,local_port = self.hex_to_ip(tcp_tmp[1])
|
||||
if local_ip == '127.0.0.1': continue
|
||||
remote_ip,remote_port = self.hex_to_ip(tcp_tmp[2])
|
||||
if local_ip == remote_ip: continue
|
||||
if remote_ip == '0.0.0.0': continue
|
||||
|
||||
pid = self.inode_to_pid(inode,force)
|
||||
if not pid: continue
|
||||
|
||||
key = self.get_ip_pack(local_ip) + b':' + self.get_port_pack(local_port)
|
||||
self.__net_process_list[key] = pid
|
||||
return self.__net_process_list
|
||||
|
||||
|
||||
def get_port_pack(self,port):
|
||||
'''
|
||||
@name 将端口转换为字节流
|
||||
@author hwliang<2021-09-13>
|
||||
@param port<int> 端口
|
||||
@return bytes
|
||||
'''
|
||||
return struct.pack('H',int(port))[::-1]
|
||||
|
||||
def get_ip_pack(self,ip):
|
||||
'''
|
||||
@name 将IP地址转换为字节流
|
||||
@author hwliang<2021-09-13>
|
||||
@param ip<str> IP地址
|
||||
@return bytes
|
||||
'''
|
||||
ip_arr = ip.split('.')
|
||||
ip_pack = b''
|
||||
for i in ip_arr:
|
||||
ip_pack += struct.pack('B',int(i))
|
||||
return ip_pack
|
||||
|
||||
def inode_to_pid(self,inode,force = False):
|
||||
'''
|
||||
@name 将inode转换为进程ID
|
||||
@author hwliang<2021-09-13>
|
||||
@param inode<string> inode
|
||||
@param force<bool> 是否强制刷新
|
||||
@return int
|
||||
'''
|
||||
inode_list = self.get_process_inodes()
|
||||
if inode in inode_list:
|
||||
return inode_list[inode]
|
||||
return None
|
||||
|
||||
def get_process_inodes(self,force = False):
|
||||
'''
|
||||
@name 获取进程inode列表
|
||||
@author hwliang<2021-09-13>
|
||||
@param force<bool> 是否强制刷新
|
||||
@return dict
|
||||
'''
|
||||
if not force and self.__inode_list: return self.__inode_list
|
||||
proc_path = '/proc'
|
||||
inode_list = {}
|
||||
for pid in os.listdir(proc_path):
|
||||
try:
|
||||
if not pid.isdigit(): continue
|
||||
inode_path = proc_path + '/' + pid + '/fd'
|
||||
for fd in os.listdir(inode_path):
|
||||
try:
|
||||
fd_file = inode_path + '/' + fd
|
||||
fd_link = os.readlink(fd_file)
|
||||
if fd_link.startswith('socket:['):
|
||||
inode = fd_link[8:-1]
|
||||
inode_list[inode] = pid
|
||||
except:
|
||||
continue
|
||||
except:
|
||||
continue
|
||||
self.__inode_list = inode_list
|
||||
return inode_list
|
||||
|
||||
def get_process_name(self,pid):
|
||||
'''
|
||||
@name 获取进程名称
|
||||
@author hwliang<2021-09-13>
|
||||
@param pid<str> 进程ID
|
||||
@return str
|
||||
'''
|
||||
pid_path = '/proc/' + pid + '/comm'
|
||||
if not os.path.exists(pid_path): return ''
|
||||
pid_file = open(pid_path, 'rb')
|
||||
pid_name = pid_file.read().decode('utf-8').strip()
|
||||
pid_file.close()
|
||||
return pid_name
|
||||
|
||||
|
||||
def write_pid(self):
|
||||
'''
|
||||
@name 写入进程ID到PID文件
|
||||
@author hwliang<2021-09-13>
|
||||
@return void
|
||||
'''
|
||||
self_pid = os.getpid()
|
||||
pid_file = open(self.__pid_file,'w')
|
||||
pid_file.write(str(self_pid))
|
||||
pid_file.close()
|
||||
|
||||
def rm_pid_file(self):
|
||||
'''
|
||||
@name 删除进程pid文件
|
||||
@author hwliang<2021-09-13>
|
||||
@return void
|
||||
'''
|
||||
if os.path.exists(self.__pid_file):
|
||||
os.remove(self.__pid_file)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) > 1:
|
||||
timeout = int(sys.argv[-1])
|
||||
else:
|
||||
timeout = 0
|
||||
p = process_network_total()
|
||||
p.write_pid()
|
||||
p.start(timeout)
|
||||
Executable
+1182
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user