Commit 7edb84c9 authored by wanli's avatar wanli

update

parent c739dee8
''' '''
Author: your name Author: your name
Date: 2021-06-29 19:33:41 Date: 2021-06-29 19:33:41
LastEditTime: 2021-07-05 09:26:59 LastEditTime: 2021-07-05 16:53:48
LastEditors: Please set LastEditors LastEditors: Please set LastEditors
Description: In User Settings Edit Description: In User Settings Edit
FilePath: \evm-store\backend\view\monitor.py FilePath: \evm-store\backend\view\monitor.py
...@@ -14,7 +14,6 @@ from tornado.websocket import WebSocketHandler, WebSocketClosedError ...@@ -14,7 +14,6 @@ from tornado.websocket import WebSocketHandler, WebSocketClosedError
import json import json
import signal import signal
import time import time
import logging
import pprint import pprint
import traceback import traceback
import jwt import jwt
...@@ -22,11 +21,10 @@ from typing import ( Any,) ...@@ -22,11 +21,10 @@ from typing import ( Any,)
from threading import Timer from threading import Timer
from datetime import datetime, timedelta from datetime import datetime, timedelta
from app import config from app import config
from fullstack.log import logger
from model.monitor import session, Device, User from model.monitor import session, Device, User
from controller.monitor import insert_data, get_monitor_list, get_watch_list from controller.monitor import insert_data, get_monitor_list, get_watch_list
logger = logging.getLogger(__name__)
def datetime2secs(mydate): def datetime2secs(mydate):
return time.mktime(mydate.timetuple()) return time.mktime(mydate.timetuple())
...@@ -81,13 +79,14 @@ def pushmessage(func): ...@@ -81,13 +79,14 @@ def pushmessage(func):
msg, binary = ret msg, binary = ret
try: try:
if isinstance(msg, WebsocketResponse) or isinstance(msg, dict): if isinstance(msg, WebsocketResponse) or isinstance(msg, dict):
self.write(json.dumps(msg), binary) self.write_message(json.dumps(msg), binary)
elif isinstance(msg, str) or isinstance(msg, str): elif isinstance(msg, str) or isinstance(msg, str):
self.write(msg, binary) self.write_message(msg, binary)
else: else:
self.write(repr(msg), binary) self.write_message(repr(msg), binary)
except WebSocketClosedError as e: except WebSocketClosedError as e:
logger.error(e) logger.error(e)
traceback.print_exc()
self.on_close() self.on_close()
return send return send
...@@ -109,6 +108,7 @@ class BaseWebsocket(WebSocketHandler): ...@@ -109,6 +108,7 @@ class BaseWebsocket(WebSocketHandler):
if className not in self.handlers: if className not in self.handlers:
self.handlers[className] = set() self.handlers[className] = set()
self.handlers[className].add(self) self.handlers[className].add(self)
logger.info(self.handlers[className])
pprint.pprint(self.handlers) pprint.pprint(self.handlers)
@pushmessage @pushmessage
...@@ -118,8 +118,10 @@ class BaseWebsocket(WebSocketHandler): ...@@ -118,8 +118,10 @@ class BaseWebsocket(WebSocketHandler):
def on_close(self): def on_close(self):
className = self.__class__.__name__ className = self.__class__.__name__
logger.warning("websocket of %s is closed" % className) logger.warning("websocket of %s is closed" % className)
if className in self.handlers: if className in self.handlers and self in self.handlers[className]:
print("122 ======>", type(self.handlers), type(className), type(self.handlers[className])) # 更加健壮的处理是,这里需要增加一个self是否存在的判断
# logger.info(self.handlers[className])
# logger.info(id(self))
self.handlers[className].remove(self) self.handlers[className].remove(self)
def check_origin(self, origin): def check_origin(self, origin):
...@@ -136,7 +138,7 @@ class BaseWebsocket(WebSocketHandler): ...@@ -136,7 +138,7 @@ class BaseWebsocket(WebSocketHandler):
for item in cls._clients: for item in cls._clients:
if message.get("imei") in item.get("devices", []): if message.get("imei") in item.get("devices", []):
item.get("context").send(json.dumps(message), binary) item.get("context").send(json.dumps(message), binary)
# print(id(item.get("context"))) # item.get("context").write_message(json.dumps(message))
# className = cls.__name__ # className = cls.__name__
# message = json.dumps(message) # message = json.dumps(message)
...@@ -158,9 +160,10 @@ class NotifyHandler(BaseWebsocket): ...@@ -158,9 +160,10 @@ class NotifyHandler(BaseWebsocket):
super(NotifyHandler, self).open() super(NotifyHandler, self).open()
def on_message(self, message): def on_message(self, message):
try:
className = self.__class__.__name__ className = self.__class__.__name__
logger.info(message)
message = json.loads(message) message = json.loads(message)
try:
# 判断消息类型 # 判断消息类型
if message.get("type"): if message.get("type"):
# 获取token值,检验正确与否,获取uuid # 获取token值,检验正确与否,获取uuid
...@@ -169,7 +172,7 @@ class NotifyHandler(BaseWebsocket): ...@@ -169,7 +172,7 @@ class NotifyHandler(BaseWebsocket):
# 认证包,认证不通过,则剔除该连接 # 认证包,认证不通过,则剔除该连接
if message.get("type") == "auth": if message.get("type") == "auth":
if not message.get("token"): if not message.get("token"):
self.write(json.dumps({ "code": 400, "data": None, "msg": "token can not be null" })) self.write_message(json.dumps({ "code": 400, "data": None, "msg": "token can not be null" }))
return return
user = session.query(User).filter(User.id == payload.get("data").get("id")).all() user = session.query(User).filter(User.id == payload.get("data").get("id")).all()
...@@ -185,7 +188,7 @@ class NotifyHandler(BaseWebsocket): ...@@ -185,7 +188,7 @@ class NotifyHandler(BaseWebsocket):
self._clients.append({ self._clients.append({
'uuid': payload.get("data").get("uuid"), 'uuid': payload.get("data").get("uuid"),
'context': self, 'context': self,
'devices': lambda d:d.imei, 'devices': list(map(lambda d:d.imei, devices)),
'ts': int(time.time()) 'ts': int(time.time())
}) })
self.write_message(json.dumps({ 'code': 200, 'data': None, 'msg': 'auth passed' })) self.write_message(json.dumps({ 'code': 200, 'data': None, 'msg': 'auth passed' }))
...@@ -203,18 +206,21 @@ class NotifyHandler(BaseWebsocket): ...@@ -203,18 +206,21 @@ class NotifyHandler(BaseWebsocket):
self.write_message(json.dumps({ 'code': 200, 'data': None, 'msg': 'unkonw message packet, disconnect by server' })) self.write_message(json.dumps({ 'code': 200, 'data': None, 'msg': 'unkonw message packet, disconnect by server' }))
self.handlers[className].remove(self) self.handlers[className].remove(self)
except Exception as e: except Exception as e:
self.handlers[className].remove(self) # 认证失败会导致触发异常,这里不能remove(self),否则会导致on_close方法报错
self.write_message(json.dumps({ 'code': 400, 'data': e.args, 'msg': "server error" }))
logger.error(e) logger.error(e)
traceback.print_exc()
logger.info(message) logger.info(message)
def on_heartbeat(self): def on_heartbeat(self):
className = self.__class__.__name__
# 心跳定时器,固定间隔扫描连接列表,当连接超时,主动剔除该连接 # 心跳定时器,固定间隔扫描连接列表,当连接超时,主动剔除该连接
for i in range(len(self._clients) - 1, -1, -1): for i in range(len(self._clients) - 1, -1, -1):
if int(time.time()) - self._clients[i].get("ts") > 5: if int(time.time()) - self._clients[i].get("ts") > 5:
self._clients.remove(self._clients[i]) # self._clients.pop(i)
if self.handlers.get(className, None): del self._clients[i]
className = self.__class__.__name__
if self.handlers.get(className, None) and self in self.handlers[className]:
logger.info(self.handlers[className])
self.handlers[className].remove(self) self.handlers[className].remove(self)
self._timer = Timer(1, self.on_heartbeat) self._timer = Timer(1, self.on_heartbeat)
...@@ -231,15 +237,13 @@ class MainHandler(BaseHandler): ...@@ -231,15 +237,13 @@ class MainHandler(BaseHandler):
# self.get_query_argument('a', value) # self.get_query_argument('a', value)
# self.get_body_argument() # self.get_body_argument()
# self.request.files # self.request.files
self.write("Hello, world") self.write(json.dumps({ "msg": "Hello, world" }))
def post(self): def post(self):
data = tornado.escape.json_decode(self.request.body) data = tornado.escape.json_decode(self.request.body)
print("=====>", data, type(data)) self.write(json.dumps({ 'code': 100, 'data': data, 'msg': 'success' }))
self.write(json.dumps({ 'code': 100, 'msg': 'success' }))
message = {'imei': '12345678900005', 'system': {'free_size': 0}, 'lvgl': {'total_size': 5242880, 'free_cnt': 31, 'free_size': 1279664, 'free_biggest_size': 1205448, 'used_cnt': 832, 'used_pct': 76, 'frag_pct': 6}, 'evm': {'total_size': 2097152, 'free_size': 0, 'gc_usage': 50}, 'image': [{'uri': 'evue_launcher', 'length': 1043, 'png_total_count': 0, 'png_uncompressed_size': 0, 'png_file_size': 0}, {'uri': 'kdgs_1_storyList', 'length': 9608, 'png_total_count': 193, 'png_uncompressed_size': 370884, 'png_file_size': 209807}]} message = {'imei': '12345678900005', 'type': 'report', 'system': {'free_size': 0}, 'lvgl': {'total_size': 5242880, 'free_cnt': 31, 'free_size': 1279664, 'free_biggest_size': 1205448, 'used_cnt': 832, 'used_pct': 76, 'frag_pct': 6}, 'evm': {'total_size': 2097152, 'free_size': 0, 'gc_usage': 50}, 'image': [{'uri': 'evue_launcher', 'length': 1043, 'png_total_count': 0, 'png_uncompressed_size': 0, 'png_file_size': 0}, {'uri': 'kdgs_1_storyList', 'length': 9608, 'png_total_count': 193, 'png_uncompressed_size': 370884, 'png_file_size': 209807}]}
insert_data(message) insert_data(message)
# 这里不能使用广播,得点对点发送,有此设备的账号才能看到调试信息 # 这里不能使用广播,得点对点发送,有此设备的账号才能看到调试信息
NotifyHandler.broadcastMessage(message) NotifyHandler.broadcastMessage(message)
...@@ -303,16 +307,15 @@ class DeviceMessageHandler(BaseHandler): ...@@ -303,16 +307,15 @@ class DeviceMessageHandler(BaseHandler):
def post(self): def post(self):
data = tornado.escape.json_decode(self.request.body) data = tornado.escape.json_decode(self.request.body)
request = { data.update({ 'request': {
'host': self.request.remote_ip, 'host': self.request.remote_ip,
'path': self.request.path, 'path': self.request.path,
'protocol': self.request.protocol 'protocol': self.request.protocol
} } })
data.update({ 'request': request })
insert_data(data) insert_data(data)
data['type'] = 'report'
data['request'].update({ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") }) data['request'].update({ 'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S") })
NotifyHandler.broadcastMessage(data) NotifyHandler.broadcastMessage(data)
self.write(json.dumps({ 'code': 100, 'message': 'success' })) self.write(json.dumps({ 'code': 100, 'message': 'success' }))
......
...@@ -238,7 +238,7 @@ export const constantRoutes = [ ...@@ -238,7 +238,7 @@ export const constantRoutes = [
path: 'index', path: 'index',
name: 'Monitor', name: 'Monitor',
component: () => import('@/views/system/monitor'), component: () => import('@/views/system/monitor'),
meta: { title: 'monitor', icon: 'home' } meta: { title: '资源监视', icon: 'home' }
}] }]
}, },
{ {
......
/* /*
* @Author: your name * @Author: your name
* @Date: 2021-07-01 15:02:16 * @Date: 2021-07-01 15:02:16
* @LastEditTime: 2021-07-03 19:50:11 * @LastEditTime: 2021-07-05 15:22:36
* @LastEditors: Please set LastEditors * @LastEditors: your name
* @Description: In User Settings Edit * @Description: In User Settings Edit
* @FilePath: \evm-store\frontend\src\utils\eventBus.js * @FilePath: \evm-store\frontend\src\utils\eventBus.js
*/ */
/*
* @Author: your name
* @Date: 2021-04-14 14:12:19
* @LastEditTime: 2021-07-01 01:11:46
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \evm-store\frontend\src\utils\wsNotify.js
*/
import Vue from "vue"; import Vue from "vue";
import store from "@/store"; import store from "@/store";
......
<template> <template>
<div class="app-container"> <div class="app-container">
<el-form :inline="true" :model="form" ref="query" size="mini"> <el-form :inline="true" ref="query" size="mini">
<el-form-item label="设备"> <el-form-item label="设备">
<el-select <el-select
v-model="watch_id" v-model="device"
filterable filterable
placeholder="请输入设备名称" placeholder="请输入设备名称"
@change="onChange" @change="onChange"
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
v-for="(item, index) in watchs" v-for="(item, index) in watchs"
:key="index" :key="index"
:label="item.imei" :label="item.imei"
:value="item.id" :value="item.imei"
></el-option> ></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
...@@ -46,12 +46,8 @@ export default { ...@@ -46,12 +46,8 @@ export default {
evmList: [], evmList: [],
lvgl: {}, lvgl: {},
lvglList: [], lvglList: [],
image: [], image: {},
imageList: [], imageList: [],
form: {
start: null,
end: null,
},
}; };
}, },
components: { components: {
...@@ -59,9 +55,6 @@ export default { ...@@ -59,9 +55,6 @@ export default {
LvglChart, LvglChart,
}, },
methods: { methods: {
sendMsg() {
this.socket.send("hello,world");
},
fetchData() { fetchData() {
this.isLoading = true; this.isLoading = true;
getWatchList() getWatchList()
...@@ -69,62 +62,44 @@ export default { ...@@ -69,62 +62,44 @@ export default {
if (res.code == 200) this.watchs = res.data; if (res.code == 200) this.watchs = res.data;
}) })
.catch((err) => { .catch((err) => {
this.$message.warning(err.msg); this.$message.warning(err.msg)
}) })
.finally(() => { .finally(() => {
this.isLoading = false; this.isLoading = false;
}); });
}, },
queryData() { queryData() {
let params = { getMonitorData({
watch: this.watch_id, watch: this.watch_id,
}; })
if (this.value2 && this.value2.length) {
if (this.value2.length > 1) {
params.start = Math.ceil(this.value2[0] / 1000);
params.end = Math.ceil(this.value2[1] / 1000);
} else {
params.start = Math.ceil(this.value2[0] / 1000);
}
}
getMonitorData(params)
.then((res) => { .then((res) => {
if (res.type == "object") { if (res.type == "object") {
this.evmList = res.data.evm this.evmList = res.data.evm
this.lvglList = res.data.lvgl this.lvglList = res.data.lvgl
this.imageList = res.data.image this.imageList = res.data.image
} else {
if (params.category == "evm") this.evmList = res.data
else if (params.category == "lvgl") this.lvglList = res.data
else if (params.category == "image") this.imageList = res.data
} }
}) })
.catch((err) => { .catch((err) => {
this.$message.warning(err.msg); this.$message.warning(err.msg)
}); });
}, },
onChange(res) { onChange() {
if (!res) return null; this.processData()
var t = this.watchs.find((item) => {
return item.id == res;
});
if (t) this.device = t.imei;
// 清空之前数据
this.processData();
}, },
onSubmit() { onSubmit() {
this.queryData(); this.queryData()
}, },
onReset(formName) { onReset(formName) {
this.$refs[formName].resetFields(); this.$refs[formName].resetFields()
this.fetchData(); this.fetchData()
}, },
handleMessage(message) { handleMessage(message) {
if (!this.device) this.device = message.imei; if (!this.device) this.device = message.imei;
this.devices[message.imei] = message; this.devices[message.imei] = message;
this.watchs.push({
imei: message.imei,
id: this.watchs.length
})
this.processData() this.processData()
}, },
processData() { processData() {
...@@ -139,7 +114,6 @@ export default { ...@@ -139,7 +114,6 @@ export default {
created() { created() {
this.socket = wsNotify; this.socket = wsNotify;
wsNotify.eventBus.$on("open", (message) => { wsNotify.eventBus.$on("open", (message) => {
this.sendMsg();
this.$nextTick(() => { this.$nextTick(() => {
console.log(message); console.log(message);
}); });
...@@ -155,8 +129,6 @@ export default { ...@@ -155,8 +129,6 @@ export default {
this.handleMessage(message); this.handleMessage(message);
}); });
}); });
this.fetchData();
}, },
}; };
</script> </script>
......
...@@ -7,6 +7,7 @@ import * as echarts from "echarts"; ...@@ -7,6 +7,7 @@ import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme require("echarts/theme/macarons"); // echarts theme
import resize from "./mixins/resize"; import resize from "./mixins/resize";
import { getDateTimeString } from "@/utils/utils"; import { getDateTimeString } from "@/utils/utils";
import { wsNotify } from "@/utils/eventBus.js";
// function randomData() { // function randomData() {
// now = new Date(+now + oneDay); // now = new Date(+now + oneDay);
...@@ -50,7 +51,7 @@ export default { ...@@ -50,7 +51,7 @@ export default {
}, },
height: { height: {
type: String, type: String,
default: "350px", default: "270px",
}, },
autoResize: { autoResize: {
type: Boolean, type: Boolean,
...@@ -128,6 +129,10 @@ export default { ...@@ -128,6 +129,10 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initChart(); this.initChart();
}); });
wsNotify.eventBus.$on("resize", () => {
if (this.chart) this.chart.resize()
});
}, },
beforeDestroy() { beforeDestroy() {
if (!this.chart) { if (!this.chart) {
...@@ -202,13 +207,13 @@ export default { ...@@ -202,13 +207,13 @@ export default {
show: false, show: false,
}, },
}, },
// grid: { grid: {
// left: 10, left: 10,
// right: 10, right: 10,
// bottom: 20, bottom: 10,
// top: 30, top: 50,
// containLabel: true, containLabel: true,
// }, },
tooltip: { tooltip: {
trigger: "axis", trigger: "axis",
axisPointer: { axisPointer: {
...@@ -233,6 +238,11 @@ export default { ...@@ -233,6 +238,11 @@ export default {
}, },
legend: { legend: {
data: this.legendData, data: this.legendData,
selected: {
heap_total_size: false,
stack_total_size: false,
stack_used_size: false,
},
}, },
series: this.series, series: this.series,
}); });
......
...@@ -7,6 +7,7 @@ import * as echarts from "echarts"; ...@@ -7,6 +7,7 @@ import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme require("echarts/theme/macarons"); // echarts theme
import resize from "./mixins/resize"; import resize from "./mixins/resize";
import { getDateTimeString } from "@/utils/utils"; import { getDateTimeString } from "@/utils/utils";
import { wsNotify } from "@/utils/eventBus.js";
const seriesData = { const seriesData = {
frag_pct: [], frag_pct: [],
...@@ -31,7 +32,7 @@ export default { ...@@ -31,7 +32,7 @@ export default {
}, },
height: { height: {
type: String, type: String,
default: "350px", default: "270px",
}, },
autoResize: { autoResize: {
type: Boolean, type: Boolean,
...@@ -113,7 +114,7 @@ export default { ...@@ -113,7 +114,7 @@ export default {
data: seriesData.used_cnt, data: seriesData.used_cnt,
}, },
{ {
name: "used_pctused_pct", name: "used_pct",
type: "line", type: "line",
showSymbol: false, showSymbol: false,
emphasis: { emphasis: {
...@@ -152,6 +153,10 @@ export default { ...@@ -152,6 +153,10 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initChart(); this.initChart();
}); });
wsNotify.eventBus.$on("resize", () => {
if (this.chart) this.chart.resize()
});
}, },
beforeDestroy() { beforeDestroy() {
if (!this.chart) { if (!this.chart) {
...@@ -201,10 +206,17 @@ export default { ...@@ -201,10 +206,17 @@ export default {
title: { title: {
text: "LVGL", text: "LVGL",
}, },
grid: {
left: 10,
right: 10,
bottom: 10,
top: 50,
containLabel: true,
},
xAxis: { xAxis: {
type: "time", type: "time",
splitLine: { splitLine: {
show: false,
}, },
axisLabel: { axisLabel: {
formatter: "{HH}:{mm}:{ss}", formatter: "{HH}:{mm}:{ss}",
...@@ -214,7 +226,7 @@ export default { ...@@ -214,7 +226,7 @@ export default {
type: "value", type: "value",
// boundaryGap: [0, "100%"], // boundaryGap: [0, "100%"],
splitLine: { splitLine: {
show: false,
}, },
}, },
tooltip: { tooltip: {
...@@ -227,6 +239,13 @@ export default { ...@@ -227,6 +239,13 @@ export default {
}, },
legend: { legend: {
data: this.legendData, data: this.legendData,
selected: {
frag_pct: false,
free_biggest_size: false,
free_cnt: false,
free_size: false,
total_size: false,
},
}, },
series: this.series, series: this.series,
}); });
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment