mirror of https://github.com/tp4a/teleport
dashboard的CPU负载和内存用量展示可用了。
parent
145e3a0d5c
commit
5b8f882f61
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
$app.on_init = function (cb_stack) {
|
||||
$app.MAX_OVERLOAD_DATA = 20;
|
||||
$app.MAX_OVERLOAD_DATA = 10 * 60 / 5;
|
||||
$app.dom = {
|
||||
count_user: $('#count-user')
|
||||
, count_host: $('#count-host')
|
||||
|
@ -12,7 +12,7 @@ $app.on_init = function (cb_stack) {
|
|||
// refresh basic info every 1m.
|
||||
$app.load_basic_info();
|
||||
// refresh overload info every 5m.
|
||||
$app.load_overload_info();
|
||||
//$app.load_overload_info();
|
||||
|
||||
$app.ws = null;
|
||||
$app.init_ws();
|
||||
|
@ -42,50 +42,40 @@ $app.load_basic_info = function () {
|
|||
setTimeout($app.load_basic_info, 60 * 1000);
|
||||
};
|
||||
|
||||
$app.load_overload_info = function () {
|
||||
$app.init_sys_status_info = function (data) {
|
||||
var i = 0;
|
||||
// var bar_x = [];
|
||||
// for (i = 0; i < $app.MAX_OVERLOAD_DATA; i++) {
|
||||
// bar_x.push(i);
|
||||
// }
|
||||
// var t = (Math.floor(Date.now() / 1000) - $app.MAX_OVERLOAD_DATA - 1) * 1000;
|
||||
console.log(data);
|
||||
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
console.log('now', now);
|
||||
//=====================================
|
||||
// CPU
|
||||
//=====================================
|
||||
|
||||
$app.bar_cpu_user = [];
|
||||
$app.bar_cpu_sys = [];
|
||||
var t = tp_local2utc(now - $app.MAX_OVERLOAD_DATA - 1);
|
||||
console.log(t);
|
||||
for (i = 0; i < $app.MAX_OVERLOAD_DATA; i++) {
|
||||
var x = t + i;
|
||||
console.log(x, t);
|
||||
$app.bar_cpu_user.push([
|
||||
{
|
||||
name: x.toString()
|
||||
, value: [tp_format_datetime(tp_utc2local(x)), 0]
|
||||
}
|
||||
]);
|
||||
$app.bar_cpu_sys.push([
|
||||
{
|
||||
name: x.toString()
|
||||
, value: [tp_format_datetime(tp_utc2local(x)), 0]
|
||||
}
|
||||
]);
|
||||
for (i = 0; i < data.length; i++) {
|
||||
// var x = t + i * 1000;
|
||||
$app.bar_cpu_user.push({name: tp_format_datetime(tp_utc2local(data[i].t), 'HH:mm:ss'), value: [tp_utc2local(data[i].t)*1000, data[i].c.u]});
|
||||
$app.bar_cpu_sys.push({name: tp_format_datetime(tp_utc2local(data[i].t), 'HH:mm:ss'), value: [tp_utc2local(data[i].t)*1000, data[i].c.s]});
|
||||
}
|
||||
//console.log('--', $app.bar_cpu_data);
|
||||
|
||||
var clr_user = '#e2524c';
|
||||
var clr_user_area = '#f7827a';
|
||||
var clr_sys = '#558c5a';
|
||||
var clr_sys_area = '#3dc34a';
|
||||
|
||||
$app.bar_cpu = echarts.init(document.getElementById('bar-cpu'));
|
||||
$app.bar_cpu.setOption({
|
||||
title: {
|
||||
// show: false
|
||||
text: 'CPU负载'
|
||||
, top: 0
|
||||
, left: 50
|
||||
, textStyle: {
|
||||
color: 'rgba(0,0,0,0.5)'
|
||||
, fontSize: 14
|
||||
text: 'CPU负载',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
color: 'rgba(0,0,0,0.5)',
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
color: [clr_sys, clr_user],
|
||||
grid: {
|
||||
show: true
|
||||
, left: 30
|
||||
|
@ -94,54 +84,151 @@ $app.load_overload_info = function () {
|
|||
, bottom: 20
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
, formatter: function (params) {
|
||||
console.log(params);
|
||||
//params = params[0];
|
||||
var t = parseInt(params[0].name);
|
||||
return tp_format_datetime(tp_utc2local(t), 'HH:mm:ss') + '<br/>' + params[0].value[1] + '%, ' + params[1].value[1] + '%';
|
||||
}
|
||||
, axisPointer: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params) {
|
||||
return params[0].name + '<br/>'+ params[1].seriesName + ': ' + params[1].value[1] + '%<br/>' + params[0].seriesName + ': ' + params[0].value[1] + '%';
|
||||
},
|
||||
axisPointer: {
|
||||
animation: false
|
||||
}
|
||||
},
|
||||
// legend: {
|
||||
// // show: false
|
||||
// },
|
||||
xAxis: {
|
||||
type: 'time'
|
||||
, boundaryGap: false
|
||||
, axisLine: {show: false}
|
||||
legend: {
|
||||
right: 20,
|
||||
data: [
|
||||
{name: '系统', icon: 'rect'},
|
||||
{name: '用户', icon: 'rect'}
|
||||
]
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
boundaryGap: false,
|
||||
splitNumber: 10,
|
||||
axisLine: {show: false}
|
||||
},
|
||||
// yAxis: {type: 'value', min: 'dataMin', axisLine: {show: false}, splitLine: {show: false}},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
, axisLine: {
|
||||
show: false
|
||||
}
|
||||
, min: 0
|
||||
, max: 100
|
||||
, boundaryGap: [0, '50%']
|
||||
type: 'value',
|
||||
axisLine: {show: false},
|
||||
min: 0,
|
||||
max: 100,
|
||||
containLabel: true
|
||||
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'cpu-sys'
|
||||
, type: 'line'
|
||||
, smooth: true
|
||||
, symbol: 'none'
|
||||
, stack: 'a'
|
||||
, showSymbol: false
|
||||
, data: $app.bar_cpu_sys
|
||||
name: '系统',
|
||||
type: 'line', smooth: true, symbol: 'none', stack: 'a', showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: clr_sys
|
||||
}, {
|
||||
offset: 1,
|
||||
color: clr_sys_area
|
||||
}])
|
||||
}
|
||||
},
|
||||
data: $app.bar_cpu_sys
|
||||
},
|
||||
{
|
||||
name: '用户', type: 'line', smooth: true, symbol: 'none', stack: 'a', showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {width: 1}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: clr_user
|
||||
}, {
|
||||
offset: 1,
|
||||
color: clr_user_area
|
||||
}])
|
||||
}
|
||||
},
|
||||
data: $app.bar_cpu_user
|
||||
}
|
||||
, {
|
||||
name: 'cpu-user'
|
||||
, type: 'line'
|
||||
, smooth: true
|
||||
, symbol: 'none'
|
||||
, stack: 'a'
|
||||
, showSymbol: false
|
||||
, data: $app.bar_cpu_user
|
||||
]
|
||||
});
|
||||
|
||||
//=====================================
|
||||
// Memory
|
||||
//=====================================
|
||||
|
||||
$app.bar_mem_used = [];
|
||||
for (i = 0; i < data.length; i++) {
|
||||
$app.bar_mem_used.push({name: tp_format_datetime(tp_utc2local(data[i].t), 'HH:mm:ss'), value: [tp_utc2local(data[i].t)*1000, tp_digital_precision(data[i].m.u * 100 / data[i].m.t, 1)]});
|
||||
}
|
||||
|
||||
var clr_mem = '#5671e2';
|
||||
var clr_mem_area = '#8da4f9';
|
||||
|
||||
$app.bar_mem = echarts.init(document.getElementById('bar-mem'));
|
||||
$app.bar_mem.setOption({
|
||||
title: {
|
||||
text: '内存用量',
|
||||
top: 0,
|
||||
textStyle: {
|
||||
color: 'rgba(0,0,0,0.5)',
|
||||
fontSize: 14
|
||||
}
|
||||
},
|
||||
color: [clr_mem],
|
||||
grid: {
|
||||
show: true
|
||||
, left: 30
|
||||
, right: 20
|
||||
, top: 30
|
||||
, bottom: 20
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
formatter: function (params) {
|
||||
return params[0].name + ': '+ params[0].value[1] + '%';
|
||||
},
|
||||
axisPointer: {
|
||||
animation: false
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'time',
|
||||
boundaryGap: false,
|
||||
splitNumber: 10,
|
||||
axisLine: {show: false}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLine: {show: false},
|
||||
min: 0,
|
||||
max: 100,
|
||||
containLabel: true
|
||||
},
|
||||
series: [
|
||||
{
|
||||
//name: '系统',
|
||||
type: 'line', smooth: true, symbol: 'none', stack: 'a', showSymbol: false,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
width: 1
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: clr_mem
|
||||
}, {
|
||||
offset: 1,
|
||||
color: clr_mem_area
|
||||
}])
|
||||
}
|
||||
},
|
||||
data: $app.bar_mem_used
|
||||
}
|
||||
]
|
||||
});
|
||||
|
@ -155,8 +242,9 @@ $app.init_ws = function () {
|
|||
$app.ws = new WebSocket('ws://' + location.host + '/ws/' + _sid);
|
||||
|
||||
$app.ws.onopen = function (e) {
|
||||
$app.ws.send('{"method": "request", "param": "sys_status"}');
|
||||
// 订阅:
|
||||
$app.ws.send('{"method": "subscribe", "params": ["sys_real_status"]}');
|
||||
// $app.ws.send('{"method": "subscribe", "params": ["sys_status"]}');
|
||||
};
|
||||
$app.ws.onclose = function (e) {
|
||||
// console.log('[ws] ws-on-close', e);
|
||||
|
@ -164,36 +252,28 @@ $app.init_ws = function () {
|
|||
};
|
||||
$app.ws.onmessage = function (e) {
|
||||
var t = JSON.parse(e.data);
|
||||
// console.log('[ws] ws-on-message', t);
|
||||
// console.log(t);
|
||||
|
||||
if (t.subscribe === 'sys_real_status') {
|
||||
if (t.method === 'request' && t.param === 'sys_status') {
|
||||
$app.init_sys_status_info(t.data);
|
||||
// 订阅系统状态信息
|
||||
$app.ws.send('{"method": "subscribe", "params": ["sys_status"]}');
|
||||
return;
|
||||
}
|
||||
|
||||
if (t.method === 'subscribe' && t.param === 'sys_status') {
|
||||
$app.bar_cpu_user.shift();
|
||||
$app.bar_cpu_user.push({
|
||||
'name': t.data.t.toString(),
|
||||
'value': [tp_format_datetime(tp_utc2local(t.data.t)), t.data.c.u]
|
||||
});
|
||||
$app.bar_cpu_user.push({name: tp_format_datetime(tp_utc2local(t.data.t), 'HH:mm:ss'), value: [tp_utc2local(t.data.t) * 1000, t.data.c.u]});
|
||||
$app.bar_cpu_sys.shift();
|
||||
$app.bar_cpu_sys.push({
|
||||
'name': t.data.t.toString(),
|
||||
'value': [tp_format_datetime(tp_utc2local(t.data.t)), t.data.c.s]
|
||||
});
|
||||
//console.log($app.bar_cpu_data);
|
||||
console.log('--', t.data.t);
|
||||
|
||||
$app.bar_cpu_sys.push({name: tp_format_datetime(tp_utc2local(t.data.t), 'HH:mm:ss'), value: [tp_utc2local(t.data.t) * 1000, t.data.c.s]});
|
||||
$app.bar_cpu.setOption(
|
||||
{
|
||||
// xAxis: {data: 1},
|
||||
series: [
|
||||
{
|
||||
name: 'cpu-user'
|
||||
, data: $app.bar_cpu_user
|
||||
}
|
||||
, {
|
||||
name: 'cpu-sys'
|
||||
, data: $app.bar_cpu_sys
|
||||
}
|
||||
]
|
||||
}
|
||||
{series: [{data: $app.bar_cpu_sys}, {data: $app.bar_cpu_user}]}
|
||||
);
|
||||
|
||||
$app.bar_mem_used.shift();
|
||||
$app.bar_mem_used.push({name: tp_format_datetime(tp_utc2local(t.data.t), 'HH:mm:ss'), value: [tp_utc2local(t.data.t) * 1000, Math.round(t.data.m.u / t.data.m.t * 100, 2)]});
|
||||
$app.bar_mem.setOption(
|
||||
{series: [{data: $app.bar_mem_used}]}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
|
@ -54,13 +54,13 @@ function tp_check_ip(ip) {
|
|||
// useful functions.
|
||||
//===================================================
|
||||
|
||||
function digital_precision(num, keep) {
|
||||
function tp_digital_precision(num, keep) {
|
||||
return Math.round(num * Math.pow(10, keep)) / Math.pow(10, keep);
|
||||
}
|
||||
|
||||
function prefixInteger(num, length) {
|
||||
return (num / Math.pow(10, length)).toFixed(length).substr(2);
|
||||
}
|
||||
// function prefixInteger(num, length) {
|
||||
// return (num / Math.pow(10, length)).toFixed(length).substr(2);
|
||||
// }
|
||||
|
||||
function tp_size2str(size, precision) {
|
||||
precision = precision || 0;
|
||||
|
@ -71,23 +71,23 @@ function tp_size2str(size, precision) {
|
|||
k = 'B';
|
||||
}
|
||||
else if (size < MB) {
|
||||
s = digital_precision(size / KB, precision);
|
||||
s = tp_digital_precision(size / KB, precision);
|
||||
k = 'KB'
|
||||
}
|
||||
else if (size < GB) {
|
||||
s = digital_precision(size / MB, precision);
|
||||
s = tp_digital_precision(size / MB, precision);
|
||||
k = 'MB'
|
||||
}
|
||||
else if (size < TB) {
|
||||
s = digital_precision(size / GB, precision);
|
||||
s = tp_digital_precision(size / GB, precision);
|
||||
k = 'GB'
|
||||
}
|
||||
else if (size < PB) {
|
||||
s = digital_precision(size / TB, precision);
|
||||
s = tp_digital_precision(size / TB, precision);
|
||||
k = 'TB'
|
||||
}
|
||||
else {
|
||||
s = digital_precision(size / PB, precision);
|
||||
s = tp_digital_precision(size / PB, precision);
|
||||
k = 'PB'
|
||||
}
|
||||
|
||||
|
|
|
@ -70,15 +70,13 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="stats stats-bar">
|
||||
## <div class="stats-name">CPU负载</div>
|
||||
<div class="stats-value" id="bar-cpu" style="height:260px;">
|
||||
<div class="stats-value" id="bar-cpu" style="height:180px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="stats stats-bar">
|
||||
<div class="stats-name">内存使用</div>
|
||||
<div class="stats-value">
|
||||
<div class="stats-value" id="bar-mem" style="height:180px;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -7,12 +7,15 @@ from app.base.logger import log
|
|||
from app.base.configs import tp_cfg
|
||||
|
||||
|
||||
class SessionManager(threading.Thread):
|
||||
# class SessionManager(threading.Thread):
|
||||
class SessionManager(object):
|
||||
|
||||
# SESSION_EXPIRE = 3600 # 60*60 默认超时时间为1小时
|
||||
_expire = 3600
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name='session-manager-thread')
|
||||
# super().__init__(name='session-manager-thread')
|
||||
super().__init__()
|
||||
|
||||
import builtins
|
||||
if '__session_manager__' in builtins.__dict__:
|
||||
|
@ -26,39 +29,48 @@ class SessionManager(threading.Thread):
|
|||
self._stop_flag = False
|
||||
self._timer_cond = threading.Condition()
|
||||
|
||||
self.update_default_expire()
|
||||
|
||||
def init(self):
|
||||
self.update_default_expire()
|
||||
return True
|
||||
|
||||
def update_default_expire(self):
|
||||
self._expire = tp_cfg().sys.login.session_timeout * 60
|
||||
|
||||
def stop(self):
|
||||
self._stop_flag = True
|
||||
self._timer_cond.acquire()
|
||||
self._timer_cond.notify()
|
||||
self._timer_cond.release()
|
||||
self.join()
|
||||
log.v('{} stopped.\n'.format(self.name))
|
||||
# def stop(self):
|
||||
# self._stop_flag = True
|
||||
# self._timer_cond.acquire()
|
||||
# self._timer_cond.notify()
|
||||
# self._timer_cond.release()
|
||||
# self.join()
|
||||
# log.v('{} stopped.\n'.format(self.name))
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
self._timer_cond.acquire()
|
||||
# 每隔一分钟醒来检查一次超时的会话
|
||||
self._timer_cond.wait(60)
|
||||
self._timer_cond.release()
|
||||
if self._stop_flag:
|
||||
break
|
||||
# def run(self):
|
||||
# while True:
|
||||
# self._timer_cond.acquire()
|
||||
# # 每隔一分钟醒来检查一次超时的会话
|
||||
# self._timer_cond.wait(60)
|
||||
# self._timer_cond.release()
|
||||
# if self._stop_flag:
|
||||
# break
|
||||
#
|
||||
# _now = int(datetime.datetime.utcnow().timestamp())
|
||||
# with self._lock:
|
||||
# _keys = [k for k in self._session_dict]
|
||||
# for k in _keys:
|
||||
# if self._session_dict[k]['e'] == 0:
|
||||
# continue
|
||||
# if _now - self._session_dict[k]['t'] > self._session_dict[k]['e']:
|
||||
# del self._session_dict[k]
|
||||
|
||||
_now = int(datetime.datetime.utcnow().timestamp())
|
||||
with self._lock:
|
||||
_keys = [k for k in self._session_dict]
|
||||
for k in _keys:
|
||||
if self._session_dict[k]['e'] == 0:
|
||||
continue
|
||||
if _now - self._session_dict[k]['t'] > self._session_dict[k]['e']:
|
||||
del self._session_dict[k]
|
||||
def check_expire(self):
|
||||
_now = int(datetime.datetime.utcnow().timestamp())
|
||||
with self._lock:
|
||||
_keys = [k for k in self._session_dict]
|
||||
for k in _keys:
|
||||
if self._session_dict[k]['e'] == 0:
|
||||
continue
|
||||
if _now - self._session_dict[k]['t'] > self._session_dict[k]['e']:
|
||||
del self._session_dict[k]
|
||||
|
||||
def set(self, s_id, value, expire=None):
|
||||
"""
|
||||
|
|
|
@ -8,24 +8,22 @@ import json
|
|||
|
||||
from app.base.logger import log
|
||||
from app.base.utils import tp_timestamp_utc_now
|
||||
from app.base.configs import tp_cfg
|
||||
from app.controller.ws import tp_wss
|
||||
from app.base.cron import tp_corn
|
||||
|
||||
|
||||
class TPSysStatus(threading.Thread):
|
||||
class TPSysStatus(object):
|
||||
_INTERVAL = 5 # seconds
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(name='sys-status-thread')
|
||||
super().__init__()
|
||||
|
||||
import builtins
|
||||
if '__tp_sys_status__' in builtins.__dict__:
|
||||
raise RuntimeError('TPSysStatus object exists, you can not create more than one instance.')
|
||||
|
||||
# session表,session_id为索引,每个项为一个字典,包括 v(value), t(last access), e(expire seconds)
|
||||
self._session_dict = dict()
|
||||
|
||||
self._stop_flag = False
|
||||
self._time_cnt = 0
|
||||
self._interval = 2
|
||||
# 实时数据我们在内存中保留最近10分钟的数据,每5秒收集一次,共 10*60/5 = 120 条记录
|
||||
self._history = list()
|
||||
|
||||
self._disk_read = 0
|
||||
self._disk_write = 0
|
||||
|
@ -33,6 +31,19 @@ class TPSysStatus(threading.Thread):
|
|||
self._net_sent = 0
|
||||
|
||||
def init(self):
|
||||
t = tp_timestamp_utc_now() - 10 * 60
|
||||
cnt = int((10 * 60 + self._INTERVAL - 1) / self._INTERVAL)
|
||||
for i in range(cnt):
|
||||
val = {
|
||||
't': t,
|
||||
'c': {'u': 0, 's': 0},
|
||||
'm': {'u': 1, 't': 100},
|
||||
'd': {'r': 0, 'w': 0},
|
||||
'n': {'r': 0, 's': 0}
|
||||
}
|
||||
self._history.append(val)
|
||||
t += self._INTERVAL
|
||||
|
||||
psutil.cpu_times_percent()
|
||||
net = psutil.net_io_counters(pernic=False)
|
||||
self._net_recv = net.bytes_recv
|
||||
|
@ -41,70 +52,59 @@ class TPSysStatus(threading.Thread):
|
|||
self._disk_read = disk.read_bytes
|
||||
self._disk_write = disk.write_bytes
|
||||
|
||||
tp_corn().add_job('sys_status', self._check_status, first_interval_seconds=self._INTERVAL, interval_seconds=self._INTERVAL)
|
||||
tp_wss().register_get_sys_status_callback(self.get_status)
|
||||
return True
|
||||
|
||||
def stop(self):
|
||||
self._stop_flag = True
|
||||
self.join()
|
||||
log.v('{} stopped.\n'.format(self.name))
|
||||
def _check_status(self):
|
||||
# time.sleep(self._interval)
|
||||
val = {'t': tp_timestamp_utc_now()}
|
||||
|
||||
def run(self):
|
||||
while not self._stop_flag:
|
||||
# time.sleep(1)
|
||||
# if self._stop_flag:
|
||||
# break
|
||||
# self._time_cnt += 1
|
||||
# if self._time_cnt < 5:
|
||||
# continue
|
||||
#
|
||||
# self._time_cnt = 0
|
||||
cpu = psutil.cpu_times_percent()
|
||||
# print(int(cpu.user * 100), int(cpu.system * 100))
|
||||
val['c'] = {'u': cpu.user, 's': cpu.system}
|
||||
#
|
||||
mem = psutil.virtual_memory()
|
||||
val['m'] = {'u': mem.used, 't': mem.total}
|
||||
# print(mem.total, mem.used, int(mem.used * 100 / mem.total))
|
||||
|
||||
time.sleep(self._interval)
|
||||
val = {'t': tp_timestamp_utc_now()}
|
||||
disk = psutil.disk_io_counters(perdisk=False)
|
||||
# val['d'] = {'r': disk.read_byes, 'w': disk.write_bytes}
|
||||
# print(disk.read_bytes, disk.write_bytes)
|
||||
_read = disk.read_bytes - self._disk_read
|
||||
_write = disk.write_bytes - self._disk_write
|
||||
self._disk_read = disk.read_bytes
|
||||
self._disk_write = disk.write_bytes
|
||||
|
||||
cpu = psutil.cpu_times_percent()
|
||||
# print(int(cpu.user * 100), int(cpu.system * 100))
|
||||
val['c'] = {'u': cpu.user, 's': cpu.system}
|
||||
#
|
||||
mem = psutil.virtual_memory()
|
||||
val['m'] = {'u': mem.used, 't': mem.total}
|
||||
# print(mem.total, mem.used, int(mem.used * 100 / mem.total))
|
||||
if _read < 0:
|
||||
_read = 0
|
||||
if _write < 0:
|
||||
_write = 0
|
||||
val['d'] = {'r': int(_read / self._INTERVAL), 'w': int(_write / self._INTERVAL)}
|
||||
# print(int(_read / self._interval), int(_write / self._interval))
|
||||
|
||||
disk = psutil.disk_io_counters(perdisk=False)
|
||||
# val['d'] = {'r': disk.read_byes, 'w': disk.write_bytes}
|
||||
# print(disk.read_bytes, disk.write_bytes)
|
||||
_read = disk.read_bytes - self._disk_read
|
||||
_write = disk.write_bytes - self._disk_write
|
||||
self._disk_read = disk.read_bytes
|
||||
self._disk_write = disk.write_bytes
|
||||
net = psutil.net_io_counters(pernic=False)
|
||||
_recv = net.bytes_recv - self._net_recv
|
||||
_sent = net.bytes_sent - self._net_sent
|
||||
self._net_recv = net.bytes_recv
|
||||
self._net_sent = net.bytes_sent
|
||||
|
||||
if _read < 0:
|
||||
_read = 0
|
||||
if _write < 0:
|
||||
_write = 0
|
||||
val['d'] = {'r': _read, 'w': _write}
|
||||
# print(int(_read / self._interval), int(_write / self._interval))
|
||||
# On some systems such as Linux, on a very busy or long-lived system, the numbers
|
||||
# returned by the kernel may overflow and wrap (restart from zero)
|
||||
if _recv < 0:
|
||||
_recv = 0
|
||||
if _sent < 0:
|
||||
_sent = 0
|
||||
val['n'] = {'r': int(_recv / self._INTERVAL), 's': int(_sent / self._INTERVAL)}
|
||||
# print(int(_recv / self._interval), int(_sent / self._interval))
|
||||
|
||||
net = psutil.net_io_counters(pernic=False)
|
||||
_recv = net.bytes_recv - self._net_recv
|
||||
_sent = net.bytes_sent - self._net_sent
|
||||
self._net_recv = net.bytes_recv
|
||||
self._net_sent = net.bytes_sent
|
||||
self._history.pop(0)
|
||||
self._history.append(val)
|
||||
|
||||
# On some systems such as Linux, on a very busy or long-lived system, the numbers
|
||||
# returned by the kernel may overflow and wrap (restart from zero)
|
||||
if _recv < 0:
|
||||
_recv = 0
|
||||
if _sent < 0:
|
||||
_sent = 0
|
||||
val['n'] = {'r': _recv, 's': _sent}
|
||||
# print(int(_recv / self._interval), int(_sent / self._interval))
|
||||
tp_wss().send_message('sys_status', val)
|
||||
|
||||
# s = json.dumps(val, separators=(',', ':'))
|
||||
|
||||
tp_wss().send_message('sys_real_status', val)
|
||||
|
||||
# print(s)
|
||||
def get_status(self):
|
||||
return self._history
|
||||
|
||||
|
||||
def tp_sys_status():
|
||||
|
|
|
@ -15,7 +15,7 @@ from app.base.configs import tp_cfg
|
|||
from app.base.db import get_db
|
||||
from app.base.logger import log
|
||||
from app.base.session import tp_session
|
||||
# from app.base.cron import tp_corn
|
||||
from app.base.cron import tp_corn
|
||||
from app.base.status import tp_sys_status
|
||||
|
||||
|
||||
|
@ -84,6 +84,9 @@ class WebApp:
|
|||
if not tp_session().init():
|
||||
log.e('can not initialize session manager.\n')
|
||||
return 0
|
||||
if not tp_sys_status().init():
|
||||
log.e('can not initialize system status collector.\n')
|
||||
return 0
|
||||
|
||||
settings = {
|
||||
#
|
||||
|
@ -130,25 +133,30 @@ class WebApp:
|
|||
log.e('can not listen on port {}:{}, make sure it not been used by another application.\n'.format(cfg.common.ip, cfg.common.port))
|
||||
return 0
|
||||
|
||||
# 启动定时任务调度器
|
||||
tp_corn().init()
|
||||
tp_corn().start()
|
||||
# 启动session超时管理
|
||||
tp_session().start()
|
||||
# tp_session().start()
|
||||
|
||||
def job():
|
||||
log.v('---job--\n')
|
||||
# def job():
|
||||
# log.v('---job--\n')
|
||||
# tp_corn().add_job('test', job, first_interval_seconds=None, interval_seconds=10)
|
||||
# tp_corn().init()
|
||||
# tp_corn().start()
|
||||
tp_sys_status().init()
|
||||
tp_sys_status().start()
|
||||
# tp_sys_status().init()
|
||||
# tp_sys_status().start()
|
||||
|
||||
tp_corn().add_job('session_expire', tp_session().check_expire, first_interval_seconds=None, interval_seconds=60)
|
||||
# tp_corn().add_job('sys_status', tp_sys_status().check_status, first_interval_seconds=5, interval_seconds=5)
|
||||
|
||||
|
||||
try:
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
except:
|
||||
log.e('\n')
|
||||
|
||||
# tp_corn().stop()
|
||||
tp_sys_status().stop()
|
||||
tp_session().stop()
|
||||
tp_corn().stop()
|
||||
# tp_sys_status().stop()
|
||||
# tp_session().stop()
|
||||
|
||||
return 0
|
||||
|
||||
|
|
|
@ -26,6 +26,11 @@ class TPWebSocketServer(object):
|
|||
if '__tp_websocket_server__' in builtins.__dict__:
|
||||
raise RuntimeError('TPWebSocketServer object exists, you can not create more than one instance.')
|
||||
|
||||
self._cb_get_sys_status = None
|
||||
|
||||
def register_get_sys_status_callback(self, cb):
|
||||
self._cb_get_sys_status = cb
|
||||
|
||||
def have_callbacker(self, callbacker):
|
||||
return callbacker in self._clients
|
||||
|
||||
|
@ -56,25 +61,24 @@ class TPWebSocketServer(object):
|
|||
for p in req['params']:
|
||||
if p not in self._clients[callbacker]['subscribe']:
|
||||
self._clients[callbacker]['subscribe'].append(p)
|
||||
elif req['method'] == 'request':
|
||||
if req['param'] == 'sys_status':
|
||||
if self._cb_get_sys_status is not None:
|
||||
message = self._cb_get_sys_status()
|
||||
msg = {'method': 'request', 'param': 'sys_status', 'data': message}
|
||||
s = json.dumps(msg, separators=(',', ':'))
|
||||
callbacker.write_message(s)
|
||||
|
||||
def send_message(self, subscribe, message):
|
||||
msg = {'subscribe': subscribe, 'data': message}
|
||||
s = json.dumps(msg, separators=(',', ':'))
|
||||
s = None
|
||||
with self._lock:
|
||||
for c in self._clients:
|
||||
|
||||
if subscribe in self._clients[c]['subscribe']:
|
||||
if s is None:
|
||||
msg = {'method': 'subscribe', 'param': subscribe, 'data': message}
|
||||
s = json.dumps(msg, separators=(',', ':'))
|
||||
c.write_message(s)
|
||||
|
||||
# def response(self, _id, data):
|
||||
# # print('send to client:', url, data)
|
||||
# for callbacker in self.clients:
|
||||
# if self.clients[callbacker].get_id() == _id:
|
||||
# print('[ws] response', _id, data)
|
||||
# callbacker.write_message(data)
|
||||
# return
|
||||
# print('## [ws] response no client.', _id)
|
||||
|
||||
|
||||
def tp_wss():
|
||||
"""
|
||||
|
@ -118,4 +122,3 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
|||
self.write_message(json.dumps(ret))
|
||||
return
|
||||
tp_wss().on_message(self, message)
|
||||
|
||||
|
|
Loading…
Reference in New Issue