Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
evm-store
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanli
evm-store
Commits
7edb84c9
Commit
7edb84c9
authored
Jul 05, 2021
by
wanli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
c739dee8
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
650 additions
and
320 deletions
+650
-320
backend/view/monitor.py
backend/view/monitor.py
+31
-28
frontend/src/router/index.js
frontend/src/router/index.js
+1
-1
frontend/src/utils/eventBus.js
frontend/src/utils/eventBus.js
+2
-10
frontend/src/views/system/chart.vue
frontend/src/views/system/chart.vue
+17
-45
frontend/src/views/system/components/EvmChart.vue
frontend/src/views/system/components/EvmChart.vue
+18
-8
frontend/src/views/system/components/LvglChart.vue
frontend/src/views/system/components/LvglChart.vue
+23
-4
frontend/src/views/system/monitor.vue
frontend/src/views/system/monitor.vue
+558
-224
No files found.
backend/view/monitor.py
View file @
7edb84c9
'''
Author: your name
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
Description: In User Settings Edit
FilePath:
\
evm-store
\b
ackend
\v
iew
\
monitor.py
...
...
@@ -14,7 +14,6 @@ from tornado.websocket import WebSocketHandler, WebSocketClosedError
import
json
import
signal
import
time
import
logging
import
pprint
import
traceback
import
jwt
...
...
@@ -22,11 +21,10 @@ from typing import ( Any,)
from
threading
import
Timer
from
datetime
import
datetime
,
timedelta
from
app
import
config
from
fullstack.log
import
logger
from
model.monitor
import
session
,
Device
,
User
from
controller.monitor
import
insert_data
,
get_monitor_list
,
get_watch_list
logger
=
logging
.
getLogger
(
__name__
)
def
datetime2secs
(
mydate
):
return
time
.
mktime
(
mydate
.
timetuple
())
...
...
@@ -81,13 +79,14 @@ def pushmessage(func):
msg
,
binary
=
ret
try
:
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
):
self
.
write
(
msg
,
binary
)
self
.
write
_message
(
msg
,
binary
)
else
:
self
.
write
(
repr
(
msg
),
binary
)
self
.
write
_message
(
repr
(
msg
),
binary
)
except
WebSocketClosedError
as
e
:
logger
.
error
(
e
)
traceback
.
print_exc
()
self
.
on_close
()
return
send
...
...
@@ -109,6 +108,7 @@ class BaseWebsocket(WebSocketHandler):
if
className
not
in
self
.
handlers
:
self
.
handlers
[
className
]
=
set
()
self
.
handlers
[
className
]
.
add
(
self
)
logger
.
info
(
self
.
handlers
[
className
])
pprint
.
pprint
(
self
.
handlers
)
@
pushmessage
...
...
@@ -118,8 +118,10 @@ class BaseWebsocket(WebSocketHandler):
def
on_close
(
self
):
className
=
self
.
__class__
.
__name__
logger
.
warning
(
"websocket of
%
s is closed"
%
className
)
if
className
in
self
.
handlers
:
print
(
"122 ======>"
,
type
(
self
.
handlers
),
type
(
className
),
type
(
self
.
handlers
[
className
]))
if
className
in
self
.
handlers
and
self
in
self
.
handlers
[
className
]:
# 更加健壮的处理是,这里需要增加一个self是否存在的判断
# logger.info(self.handlers[className])
# logger.info(id(self))
self
.
handlers
[
className
]
.
remove
(
self
)
def
check_origin
(
self
,
origin
):
...
...
@@ -136,7 +138,7 @@ class BaseWebsocket(WebSocketHandler):
for
item
in
cls
.
_clients
:
if
message
.
get
(
"imei"
)
in
item
.
get
(
"devices"
,
[]):
item
.
get
(
"context"
)
.
send
(
json
.
dumps
(
message
),
binary
)
# print(id(item.get("context")
))
# item.get("context").write_message(json.dumps(message
))
# className = cls.__name__
# message = json.dumps(message)
...
...
@@ -158,9 +160,10 @@ class NotifyHandler(BaseWebsocket):
super
(
NotifyHandler
,
self
)
.
open
()
def
on_message
(
self
,
message
):
className
=
self
.
__class__
.
__name__
message
=
json
.
loads
(
message
)
try
:
className
=
self
.
__class__
.
__name__
logger
.
info
(
message
)
message
=
json
.
loads
(
message
)
# 判断消息类型
if
message
.
get
(
"type"
):
# 获取token值,检验正确与否,获取uuid
...
...
@@ -169,7 +172,7 @@ class NotifyHandler(BaseWebsocket):
# 认证包,认证不通过,则剔除该连接
if
message
.
get
(
"type"
)
==
"auth"
:
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
user
=
session
.
query
(
User
)
.
filter
(
User
.
id
==
payload
.
get
(
"data"
)
.
get
(
"id"
))
.
all
()
...
...
@@ -185,7 +188,7 @@ class NotifyHandler(BaseWebsocket):
self
.
_clients
.
append
({
'uuid'
:
payload
.
get
(
"data"
)
.
get
(
"uuid"
),
'context'
:
self
,
'devices'
:
l
ambda
d
:
d
.
imei
,
'devices'
:
l
ist
(
map
(
lambda
d
:
d
.
imei
,
devices
))
,
'ts'
:
int
(
time
.
time
())
})
self
.
write_message
(
json
.
dumps
({
'code'
:
200
,
'data'
:
None
,
'msg'
:
'auth passed'
}))
...
...
@@ -203,18 +206,21 @@ class NotifyHandler(BaseWebsocket):
self
.
write_message
(
json
.
dumps
({
'code'
:
200
,
'data'
:
None
,
'msg'
:
'unkonw message packet, disconnect by server'
}))
self
.
handlers
[
className
]
.
remove
(
self
)
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
)
traceback
.
print_exc
()
logger
.
info
(
message
)
def
on_heartbeat
(
self
):
className
=
self
.
__class__
.
__name__
# 心跳定时器,固定间隔扫描连接列表,当连接超时,主动剔除该连接
for
i
in
range
(
len
(
self
.
_clients
)
-
1
,
-
1
,
-
1
):
if
int
(
time
.
time
())
-
self
.
_clients
[
i
]
.
get
(
"ts"
)
>
5
:
self
.
_clients
.
remove
(
self
.
_clients
[
i
])
if
self
.
handlers
.
get
(
className
,
None
):
# self._clients.pop(i)
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
.
_timer
=
Timer
(
1
,
self
.
on_heartbeat
)
...
...
@@ -231,15 +237,13 @@ class MainHandler(BaseHandler):
# self.get_query_argument('a', value)
# self.get_body_argument()
# self.request.files
self
.
write
(
"Hello, world"
)
self
.
write
(
json
.
dumps
({
"msg"
:
"Hello, world"
})
)
def
post
(
self
):
data
=
tornado
.
escape
.
json_decode
(
self
.
request
.
body
)
print
(
"=====>"
,
data
,
type
(
data
))
self
.
write
(
json
.
dumps
({
'code'
:
100
,
'msg'
:
'success'
}))
self
.
write
(
json
.
dumps
({
'code'
:
100
,
'data'
:
data
,
'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
)
# 这里不能使用广播,得点对点发送,有此设备的账号才能看到调试信息
NotifyHandler
.
broadcastMessage
(
message
)
...
...
@@ -303,16 +307,15 @@ class DeviceMessageHandler(BaseHandler):
def
post
(
self
):
data
=
tornado
.
escape
.
json_decode
(
self
.
request
.
body
)
request
=
{
data
.
update
({
'request'
:
{
'host'
:
self
.
request
.
remote_ip
,
'path'
:
self
.
request
.
path
,
'protocol'
:
self
.
request
.
protocol
}
data
.
update
({
'request'
:
request
})
}
})
insert_data
(
data
)
data
[
'type'
]
=
'report'
data
[
'request'
]
.
update
({
'timestamp'
:
datetime
.
now
()
.
strftime
(
"
%
Y-
%
m-
%
d
%
H:
%
M:
%
S"
)
})
NotifyHandler
.
broadcastMessage
(
data
)
self
.
write
(
json
.
dumps
({
'code'
:
100
,
'message'
:
'success'
}))
...
...
frontend/src/router/index.js
View file @
7edb84c9
...
...
@@ -238,7 +238,7 @@ export const constantRoutes = [
path
:
'
index
'
,
name
:
'
Monitor
'
,
component
:
()
=>
import
(
'
@/views/system/monitor
'
),
meta
:
{
title
:
'
monitor
'
,
icon
:
'
home
'
}
meta
:
{
title
:
'
资源监视
'
,
icon
:
'
home
'
}
}]
},
{
...
...
frontend/src/utils/eventBus.js
View file @
7edb84c9
/*
* @Author: your name
* @Date: 2021-07-01 15:02:16
* @LastEditTime: 2021-07-0
3 19:50:11
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-07-0
5 15:22:36
* @LastEditors:
your name
* @Description: In User Settings Edit
* @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
store
from
"
@/store
"
;
...
...
frontend/src/views/system/chart.vue
View file @
7edb84c9
<
template
>
<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-select
v-model=
"
watch_id
"
v-model=
"
device
"
filterable
placeholder=
"请输入设备名称"
@
change=
"onChange"
...
...
@@ -12,7 +12,7 @@
v-for=
"(item, index) in watchs"
:key=
"index"
:label=
"item.imei"
:value=
"item.i
d
"
:value=
"item.i
mei
"
></el-option>
</el-select>
</el-form-item>
...
...
@@ -46,12 +46,8 @@ export default {
evmList
:
[],
lvgl
:
{},
lvglList
:
[],
image
:
[]
,
image
:
{}
,
imageList
:
[],
form
:
{
start
:
null
,
end
:
null
,
},
};
},
components
:
{
...
...
@@ -59,9 +55,6 @@ export default {
LvglChart
,
},
methods
:
{
sendMsg
()
{
this
.
socket
.
send
(
"
hello,world
"
);
},
fetchData
()
{
this
.
isLoading
=
true
;
getWatchList
()
...
...
@@ -69,62 +62,44 @@ export default {
if
(
res
.
code
==
200
)
this
.
watchs
=
res
.
data
;
})
.
catch
((
err
)
=>
{
this
.
$message
.
warning
(
err
.
msg
)
;
this
.
$message
.
warning
(
err
.
msg
)
})
.
finally
(()
=>
{
this
.
isLoading
=
false
;
});
},
queryData
()
{
let
params
=
{
getMonitorData
(
{
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
)
=>
{
if
(
res
.
type
==
"
object
"
)
{
this
.
evmList
=
res
.
data
.
evm
this
.
lvglList
=
res
.
data
.
lvgl
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
)
=>
{
this
.
$message
.
warning
(
err
.
msg
)
;
this
.
$message
.
warning
(
err
.
msg
)
});
},
onChange
(
res
)
{
if
(
!
res
)
return
null
;
var
t
=
this
.
watchs
.
find
((
item
)
=>
{
return
item
.
id
==
res
;
});
if
(
t
)
this
.
device
=
t
.
imei
;
// 清空之前数据
this
.
processData
();
onChange
()
{
this
.
processData
()
},
onSubmit
()
{
this
.
queryData
()
;
this
.
queryData
()
},
onReset
(
formName
)
{
this
.
$refs
[
formName
].
resetFields
()
;
this
.
fetchData
()
;
this
.
$refs
[
formName
].
resetFields
()
this
.
fetchData
()
},
handleMessage
(
message
)
{
if
(
!
this
.
device
)
this
.
device
=
message
.
imei
;
this
.
devices
[
message
.
imei
]
=
message
;
this
.
watchs
.
push
({
imei
:
message
.
imei
,
id
:
this
.
watchs
.
length
})
this
.
processData
()
},
processData
()
{
...
...
@@ -139,7 +114,6 @@ export default {
created
()
{
this
.
socket
=
wsNotify
;
wsNotify
.
eventBus
.
$on
(
"
open
"
,
(
message
)
=>
{
this
.
sendMsg
();
this
.
$nextTick
(()
=>
{
console
.
log
(
message
);
});
...
...
@@ -155,8 +129,6 @@ export default {
this
.
handleMessage
(
message
);
});
});
this
.
fetchData
();
},
};
</
script
>
...
...
frontend/src/views/system/components/EvmChart.vue
View file @
7edb84c9
...
...
@@ -7,6 +7,7 @@ import * as echarts from "echarts";
require
(
"
echarts/theme/macarons
"
);
// echarts theme
import
resize
from
"
./mixins/resize
"
;
import
{
getDateTimeString
}
from
"
@/utils/utils
"
;
import
{
wsNotify
}
from
"
@/utils/eventBus.js
"
;
// function randomData() {
// now = new Date(+now + oneDay);
...
...
@@ -50,7 +51,7 @@ export default {
},
height
:
{
type
:
String
,
default
:
"
35
0px
"
,
default
:
"
27
0px
"
,
},
autoResize
:
{
type
:
Boolean
,
...
...
@@ -128,6 +129,10 @@ export default {
this
.
$nextTick
(()
=>
{
this
.
initChart
();
});
wsNotify
.
eventBus
.
$on
(
"
resize
"
,
()
=>
{
if
(
this
.
chart
)
this
.
chart
.
resize
()
});
},
beforeDestroy
()
{
if
(
!
this
.
chart
)
{
...
...
@@ -202,13 +207,13 @@ export default {
show
:
false
,
},
},
//
grid: {
//
left: 10,
//
right: 10,
// bottom: 2
0,
// top: 3
0,
//
containLabel: true,
//
},
grid
:
{
left
:
10
,
right
:
10
,
bottom
:
1
0
,
top
:
5
0
,
containLabel
:
true
,
},
tooltip
:
{
trigger
:
"
axis
"
,
axisPointer
:
{
...
...
@@ -233,6 +238,11 @@ export default {
},
legend
:
{
data
:
this
.
legendData
,
selected
:
{
heap_total_size
:
false
,
stack_total_size
:
false
,
stack_used_size
:
false
,
},
},
series
:
this
.
series
,
});
...
...
frontend/src/views/system/components/LvglChart.vue
View file @
7edb84c9
...
...
@@ -7,6 +7,7 @@ import * as echarts from "echarts";
require
(
"
echarts/theme/macarons
"
);
// echarts theme
import
resize
from
"
./mixins/resize
"
;
import
{
getDateTimeString
}
from
"
@/utils/utils
"
;
import
{
wsNotify
}
from
"
@/utils/eventBus.js
"
;
const
seriesData
=
{
frag_pct
:
[],
...
...
@@ -31,7 +32,7 @@ export default {
},
height
:
{
type
:
String
,
default
:
"
35
0px
"
,
default
:
"
27
0px
"
,
},
autoResize
:
{
type
:
Boolean
,
...
...
@@ -113,7 +114,7 @@ export default {
data
:
seriesData
.
used_cnt
,
},
{
name
:
"
used_pct
used_pct
"
,
name
:
"
used_pct
"
,
type
:
"
line
"
,
showSymbol
:
false
,
emphasis
:
{
...
...
@@ -152,6 +153,10 @@ export default {
this
.
$nextTick
(()
=>
{
this
.
initChart
();
});
wsNotify
.
eventBus
.
$on
(
"
resize
"
,
()
=>
{
if
(
this
.
chart
)
this
.
chart
.
resize
()
});
},
beforeDestroy
()
{
if
(
!
this
.
chart
)
{
...
...
@@ -201,10 +206,17 @@ export default {
title
:
{
text
:
"
LVGL
"
,
},
grid
:
{
left
:
10
,
right
:
10
,
bottom
:
10
,
top
:
50
,
containLabel
:
true
,
},
xAxis
:
{
type
:
"
time
"
,
splitLine
:
{
show
:
false
,
},
axisLabel
:
{
formatter
:
"
{HH}:{mm}:{ss}
"
,
...
...
@@ -214,7 +226,7 @@ export default {
type
:
"
value
"
,
// boundaryGap: [0, "100%"],
splitLine
:
{
show
:
false
,
},
},
tooltip
:
{
...
...
@@ -227,6 +239,13 @@ export default {
},
legend
:
{
data
:
this
.
legendData
,
selected
:
{
frag_pct
:
false
,
free_biggest_size
:
false
,
free_cnt
:
false
,
free_size
:
false
,
total_size
:
false
,
},
},
series
:
this
.
series
,
});
...
...
frontend/src/views/system/monitor.vue
View file @
7edb84c9
<
template
>
<div
class=
"app-container"
>
<div>
<el-select
size=
"mini"
v-model=
"device"
@
change=
"onSelectChange"
placeholder=
"请选择设备"
<div
style=
"margin-top: 10px"
>
<grid-layout
:layout.sync=
"layout"
:col-num=
"12"
:row-height=
"30"
:is-draggable=
"draggable"
:is-resizable=
"resizable"
:vertical-compact=
"true"
:use-css-transforms=
"true"
@
layout-created=
"layoutCreatedEvent"
@
layout-before-mount=
"layoutBeforeMountEvent"
@
layout-mounted=
"layoutMountedEvent"
@
layout-ready=
"layoutReadyEvent"
@
layout-updated=
"layoutUpdatedEvent"
>
<el-option
v-for=
"(item, index) in deviceList"
:key=
"index"
:label=
"item"
:value=
"item"
></el-option>
</el-select>
</div>
<h2>
REQUEST
</h2>
<el-table
element-loading-text=
"Loading"
:data=
"request"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop=
"host"
label=
"host"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"path"
label=
"path"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"timestamp"
label=
"timestamp"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
</el-table>
<h2>
SYSTEM
</h2>
<el-table
element-loading-text=
"Loading"
:data=
"system"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
label=
"imei"
min-width=
"180"
show-overflow-tooltip
>
<template
slot-scope=
"scope"
>
{{
scope
.
row
.
imei
}}
</
template
>
</el-table-column>
<el-table-column
label=
"free_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_size
}}
(KB)
</
template
>
</el-table-column>
</el-table>
<h2>
LVGL
</h2>
<el-table
element-loading-text=
"Loading"
:data=
"lvgl"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
label=
"total_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
total_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
prop=
"free_cnt"
label=
"free_cnt"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"free_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"free_biggest_size"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_biggest_size
}}
(KB)
</
template
<grid-item
:x=
"0"
:y=
"0"
:w=
"6"
:h=
"5"
i=
"1"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
<el-table-column
label=
"used_cnt"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
used_cnt
}}
</
template
>
</el-table-column>
<el-table-column
label=
"used_pct"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
used_pct
}}
(%)
</
template
>
</el-table-column>
<el-table-column
label=
"frag_pct"
min-width=
"180"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
frag_pct
}}
(%)
</
template
>
</el-table-column>
</el-table>
<h2>
EVM
</h2>
<el-table
element-loading-text=
"Loading"
:data=
"evm"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<!-- <el-table-column
label="total_size"
min-width="180"
show-overflow-tooltip
>
<template slot-scope="scope">{{ scope.row.total_size }}(KB)</template>
</el-table-column>
<el-table-column
label="free_size"
min-width="180"
show-overflow-tooltip
>
<template slot-scope="scope">{{ scope.row.free_size }}(KB)</template>
</el-table-column> -->
<el-table-column
label=
"heap_map_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_map_size
}}
(KB)
</
template
<p
class=
"item-title"
>
DEVICE
</p>
<div
style=
"padding: 15px"
>
<el-select
size=
"mini"
v-model=
"device"
@
change=
"onSelectChange"
placeholder=
"请选择设备"
>
<el-option
v-for=
"(item, index) in deviceList"
:key=
"index"
:label=
"item"
:value=
"item"
></el-option>
</el-select>
</div>
</grid-item>
<grid-item
:x=
"6"
:y=
"0"
:w=
"6"
:h=
"5"
i=
"2"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
<el-table-column
label=
"heap_total_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_total_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"heap_used_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_used_size
}}
(KB)
</
template
<p
class=
"item-title"
>
SYSTEM
</p>
<el-table
element-loading-text=
"Loading"
:data=
"system"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop=
"host"
label=
"host"
min-width=
"150"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"path"
label=
"path"
min-width=
"150"
show-overflow-tooltip
></el-table-column>
<el-table-column
prop=
"timestamp"
label=
"timestamp"
min-width=
"150"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"imei"
min-width=
"150"
show-overflow-tooltip
>
<template
slot-scope=
"scope"
>
{{
scope
.
row
.
imei
}}
</
template
>
</el-table-column>
<el-table-column
label=
"free_size"
min-width=
"100"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_size
}}
(KB)
</
template
>
</el-table-column>
</el-table>
</grid-item>
<grid-item
:x=
"0"
:y=
"5"
:w=
"6"
:h=
"5"
i=
"3"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
<el-table-column
label=
"stack_total_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
stack_total_size
}}
(KB)
</
template
<p
class=
"item-title"
>
EVM
</p>
<el-table
element-loading-text=
"Loading"
:data=
"evmList"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
label=
"heap_map_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_map_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"heap_total_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_total_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"heap_used_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
heap_used_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"stack_total_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
stack_total_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"stack_used_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
stack_used_size
}}
(KB)
</
template
>
</el-table-column>
</el-table>
</grid-item>
<grid-item
:x=
"6"
:y=
"5"
:w=
"6"
:h=
"5"
i=
"4"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
<el-table-column
label=
"stack_used_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
stack_used_size
}}
(KB)
</
template
<p
class=
"item-title"
>
LVGL
</p>
<el-table
element-loading-text=
"Loading"
:data=
"lvglList"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
label=
"total_size"
min-width=
"100"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
total_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
prop=
"free_cnt"
label=
"free_cnt"
min-width=
"100"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"free_size"
min-width=
"120"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"free_biggest_size"
min-width=
"120"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
free_biggest_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"used_cnt"
min-width=
"100"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
used_cnt
}}
</
template
>
</el-table-column>
<el-table-column
label=
"used_pct"
min-width=
"100"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
used_pct
}}
(%)
</
template
>
</el-table-column>
<el-table-column
label=
"frag_pct"
min-width=
"100"
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
frag_pct
}}
(%)
</
template
>
</el-table-column>
</el-table>
</grid-item>
<grid-item
:x=
"0"
:y=
"10"
:w=
"12"
:h=
"7"
i=
"5"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
</el-table>
<h2>
APP
</h2>
<el-table
element-loading-text=
"Loading"
:data=
"image"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop=
"uri"
label=
"uri"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"length"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
length
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"png_file_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
png_file_size
}}
(KB)
</
template
<p
class=
"item-title"
>
APP
</p>
<el-table
element-loading-text=
"Loading"
:data=
"imageList"
size=
"mini"
border
stripe
fit
highlight-current-row
>
<el-table-column
prop=
"uri"
label=
"uri"
min-width=
"150"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"length"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
length
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
label=
"png_file_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
png_file_size
}}
(KB)
</
template
>
</el-table-column>
<el-table-column
prop=
"png_total_count"
label=
"png_total_count"
min-width=
"150"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"png_uncompressed_size"
min-width=
"150"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
png_uncompressed_size
}}
(KB)
</
template
>
</el-table-column>
</el-table>
</grid-item>
<grid-item
:x=
"0"
:y=
"17"
:w=
"12"
:h=
"7"
i=
"6"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
<el-table-column
prop=
"png_total_count"
label=
"png_total_count"
min-width=
"180"
show-overflow-tooltip
></el-table-column>
<el-table-column
label=
"png_uncompressed_size"
min-width=
"180"
show-overflow-tooltip
>
<
template
slot-scope=
"scope"
>
{{
scope
.
row
.
png_uncompressed_size
}}
(KB)
</
template
<EvmChart
:chartData=
"evm"
></EvmChart>
</grid-item>
<grid-item
:x=
"0"
:y=
"24"
:w=
"12"
:h=
"7"
i=
"7"
@
resize=
"resizeEvent"
@
move=
"moveEvent"
@
resized=
"resizedEvent"
@
container-resized=
"containerResizedEvent"
@
moved=
"movedEvent"
>
</el-table-column>
</el-table>
<LvglChart
:chartData=
"lvgl"
></LvglChart>
</grid-item>
</grid-layout>
</div>
</div>
</template>
<
script
>
import
{
getWatchList
,
getMonitorData
}
from
"
@/api/index
"
;
import
EvmChart
from
"
./components/EvmChart
"
;
import
LvglChart
from
"
./components/LvglChart
"
;
import
{
GridLayout
,
GridItem
}
from
"
vue-grid-layout
"
;
import
{
wsNotify
}
from
"
@/utils/eventBus.js
"
;
export
default
{
name
:
"
Monitor
"
,
data
()
{
return
{
watchs
:
[],
device
:
null
,
devices
:
{},
deviceList
:
[]
,
deviceList
:
null
,
system
:
[],
lvgl
:
[],
evm
:
[],
image
:
[],
request
:
[],
evm
:
{},
evmList
:
[],
lvgl
:
{},
lvglList
:
[],
image
:
{},
imageList
:
[],
socket
:
null
,
form
:
{
system
:
[
"
free_size
"
],
...
...
@@ -243,24 +362,163 @@ export default {
],
image
:
[
"
png_uncompressed_size
"
,
"
png_file_size
"
,
"
length
"
],
},
layout
:
[
{
x
:
0
,
y
:
0
,
w
:
6
,
h
:
5
,
i
:
"
0
"
,
static
:
false
},
{
x
:
6
,
y
:
0
,
w
:
6
,
h
:
5
,
i
:
"
1
"
,
static
:
true
},
{
x
:
0
,
y
:
5
,
w
:
6
,
h
:
5
,
i
:
"
2
"
,
static
:
false
},
{
x
:
6
,
y
:
5
,
w
:
6
,
h
:
5
,
i
:
"
3
"
,
static
:
false
},
{
x
:
0
,
y
:
10
,
w
:
12
,
h
:
7
,
i
:
"
4
"
,
static
:
false
},
{
x
:
0
,
y
:
17
,
w
:
12
,
h
:
7
,
i
:
"
4
"
,
static
:
false
},
{
x
:
0
,
y
:
24
,
w
:
12
,
h
:
7
,
i
:
"
4
"
,
static
:
false
},
],
draggable
:
true
,
resizable
:
true
,
};
},
components
:
{
GridLayout
,
GridItem
,
EvmChart
,
LvglChart
,
},
methods
:
{
moveEvent
(
i
,
newX
,
newY
)
{
const
msg
=
"
MOVE i=
"
+
i
+
"
, X=
"
+
newX
+
"
, Y=
"
+
newY
;
console
.
log
(
msg
);
},
movedEvent
(
i
,
newX
,
newY
)
{
const
msg
=
"
MOVED i=
"
+
i
+
"
, X=
"
+
newX
+
"
, Y=
"
+
newY
;
console
.
log
(
msg
);
},
resizeEvent
(
i
,
newH
,
newW
,
newHPx
,
newWPx
)
{
const
msg
=
"
RESIZE i=
"
+
i
+
"
, H=
"
+
newH
+
"
, W=
"
+
newW
+
"
, H(px)=
"
+
newHPx
+
"
, W(px)=
"
+
newWPx
;
console
.
log
(
msg
);
},
resizedEvent
(
i
,
newX
,
newY
,
newHPx
,
newWPx
)
{
const
msg
=
"
RESIZED i=
"
+
i
+
"
, X=
"
+
newX
+
"
, Y=
"
+
newY
+
"
, H(px)=
"
+
newHPx
+
"
, W(px)=
"
+
newWPx
;
console
.
log
(
msg
);
},
containerResizedEvent
(
i
,
newH
,
newW
,
newHPx
,
newWPx
)
{
const
msg
=
"
CONTAINER RESIZED i=
"
+
i
+
"
, H=
"
+
newH
+
"
, W=
"
+
newW
+
"
, H(px)=
"
+
newHPx
+
"
, W(px)=
"
+
newWPx
;
console
.
log
(
msg
);
},
layoutCreatedEvent
(
newLayout
)
{
console
.
log
(
"
Created layout:
"
,
newLayout
);
},
layoutBeforeMountEvent
(
newLayout
)
{
console
.
log
(
"
beforeMount layout:
"
,
newLayout
);
},
layoutMountedEvent
(
newLayout
)
{
console
.
log
(
"
Mounted layout:
"
,
newLayout
);
},
layoutReadyEvent
(
newLayout
)
{
console
.
log
(
"
Ready layout:
"
,
newLayout
);
},
layoutUpdatedEvent
(
newLayout
)
{
console
.
log
(
"
Updated layout:
"
,
newLayout
);
},
fetchData
()
{
this
.
isLoading
=
true
;
getWatchList
()
.
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
this
.
watchs
=
res
.
data
;
})
.
catch
((
err
)
=>
{
this
.
$message
.
warning
(
err
.
msg
);
})
.
finally
(()
=>
{
this
.
isLoading
=
false
;
});
},
queryData
()
{
getMonitorData
({
watch
:
this
.
device
,
})
.
then
((
res
)
=>
{
if
(
res
.
type
==
"
object
"
)
{
this
.
evmList
=
res
.
data
.
evm
;
this
.
lvglList
=
res
.
data
.
lvgl
;
this
.
imageList
=
res
.
data
.
image
;
}
})
.
catch
((
err
)
=>
{
this
.
$message
.
warning
(
err
.
msg
);
});
},
onChange
(
res
)
{
if
(
!
res
)
return
null
;
var
t
=
this
.
watchs
.
find
((
item
)
=>
{
return
item
.
id
==
res
;
});
if
(
t
)
this
.
device
=
t
.
imei
;
// 清空之前数据
this
.
resetData
();
},
onSubmit
()
{
this
.
queryData
();
},
onReset
(
formName
)
{
this
.
$refs
[
formName
].
resetFields
();
this
.
fetchData
();
},
sendMsg
()
{
let
message
=
JSON
.
stringify
({
type
:
"
auth
"
,
token
:
this
.
$store
.
getters
.
token
});
let
message
=
JSON
.
stringify
({
type
:
"
auth
"
,
token
:
this
.
$store
.
getters
.
token
,
});
this
.
socket
.
send
(
message
);
},
handleMessage
(
msg
)
{
if
(
!
this
.
deviceList
.
includes
(
msg
.
imei
))
{
if
(
msg
.
type
!==
"
report
"
)
return
false
;
if
(
this
.
deviceList
&&
!
this
.
deviceList
.
includes
(
msg
.
imei
))
{
this
.
deviceList
.
push
(
msg
.
imei
);
}
if
(
!
this
.
device
)
{
if
(
!
this
.
device
&&
this
.
deviceList
)
{
this
.
device
=
this
.
deviceList
[
0
];
}
else
{
this
.
device
=
msg
.
imei
}
this
.
devices
[
msg
.
imei
]
=
msg
;
this
.
processData
(
this
.
devices
[
this
.
device
]);
this
.
resetData
();
},
processData
(
msg
)
{
console
.
log
(
msg
)
if
(
!
msg
)
return
null
;
Object
.
keys
(
msg
).
forEach
((
item
)
=>
{
if
(
this
.
form
[
item
])
{
var
keys
=
this
.
form
[
item
];
...
...
@@ -277,27 +535,42 @@ export default {
}
});
this
.
system
=
[{
imei
:
msg
.
imei
,
...
msg
.
system
}];
this
.
lvgl
=
[{
...
msg
.
lvgl
}];
this
.
evm
=
[{
...
msg
.
evm
}];
this
.
request
=
[{
...
msg
.
request
}];
console
.
log
(
msg
)
this
.
evmList
=
[{
...
msg
.
evm
}];
this
.
lvglList
=
[{
...
msg
.
lvgl
}];
this
.
system
=
[{
imei
:
msg
.
imei
,
...
msg
.
system
,
...
msg
.
request
}];
// 这里需要特殊处理下,先判断uri是否存在,不存在则添加,存在则更新
let
uris
=
[];
this
.
image
.
forEach
((
img
)
=>
{
uris
.
push
(
img
.
uri
)
this
.
image
List
.
forEach
((
img
)
=>
{
uris
.
push
(
img
.
uri
)
;
});
msg
.
image
&&
msg
.
image
.
forEach
((
item
)
=>
{
if
(
!
uris
.
includes
(
item
.
uri
))
{
this
.
image
.
push
(
item
)
}
});
// this.image = msg.image;
msg
.
image
&&
msg
.
image
.
forEach
((
item
)
=>
{
if
(
!
uris
.
includes
(
item
.
uri
))
{
this
.
imageList
.
push
(
item
);
}
});
// this.imageList = msg.image;
},
onSelectChange
(
res
)
{
this
.
device
=
res
;
this
.
processData
(
this
.
devices
[
this
.
device
]);
console
.
log
(
res
);
},
resetData
()
{
wsNotify
.
eventBus
.
$emit
(
"
resize
"
);
if
(
this
.
devices
[
this
.
device
])
{
if
(
this
.
devices
[
this
.
device
].
evm
)
this
.
evm
=
this
.
devices
[
this
.
device
].
evm
;
if
(
this
.
devices
[
this
.
device
].
lvgl
)
this
.
lvgl
=
this
.
devices
[
this
.
device
].
lvgl
;
if
(
this
.
devices
[
this
.
device
].
image
)
this
.
image
=
this
.
devices
[
this
.
device
].
image
;
}
}
},
mounted
()
{},
created
()
{
...
...
@@ -307,6 +580,7 @@ export default {
this
.
$nextTick
(()
=>
{
console
.
log
(
message
);
});
// 这里启动一个定时器,10秒钟后,如果没有消息进来,说明当前没有在线设备
});
wsNotify
.
eventBus
.
$on
(
"
close
"
,
(
message
)
=>
{
this
.
$nextTick
(()
=>
{
...
...
@@ -328,4 +602,64 @@ export default {
margin
:
10px
0px
;
}
}
.vue-grid-layout
{
background
:
#aaa
;
}
.vue-grid-item
:not
(
.vue-grid-placeholder
)
{
background
:
#fff
;
border
:
0px
solid
#eee
;
}
.vue-grid-item
.resizing
{
opacity
:
0
.9
;
}
.vue-grid-item
.static
{
background
:
#cce
;
}
.vue-grid-item
.text
{
font-size
:
24px
;
text-align
:
center
;
position
:
absolute
;
top
:
0
;
bottom
:
0
;
left
:
0
;
right
:
0
;
margin
:
auto
;
height
:
100%
;
width
:
100%
;
}
.vue-grid-item
.item-title
{
margin-left
:
15px
;
}
.vue-grid-item
.no-drag
{
height
:
100%
;
width
:
100%
;
}
.vue-grid-item
.minMax
{
font-size
:
12px
;
}
.vue-grid-item
.add
{
cursor
:
pointer
;
}
.vue-draggable-handle
{
position
:
absolute
;
width
:
20px
;
height
:
20px
;
top
:
0
;
left
:
0
;
background
:
url("data:image/svg+xml;utf8,
<
svg
xmlns
='
http
:
//
www
.
w3
.
org
/
2000
/
svg
' width='
10
' height='
10
'>
<
circle
cx
=
'5'
cy
=
'5'
r
=
'5'
fill
=
'#999999'
/></
svg
>
")
no-repeat;
background-position: bottom right;
padding: 0 8px 8px 0;
background-repeat: no-repeat;
background-origin: content-box;
box-sizing: border-box;
cursor: pointer;
}
.layoutJSON {
background: #ddd;
border: 1px solid black;
margin-top: 10px;
padding: 10px;
}
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment