1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 | """
Simple web app to monitor the CPU and memory usage of the server process.
Requires psutil.
This app might be running at the demo server: http://flexx1.zoof.io
"""
from time import time
import psutil
import asyncio
from flexx import flx
nsamples = 16
class Relay(flx.Component):
number_of_connections = flx.IntProp(settable=True)
def init(self):
self.update_number_of_connections()
self.refresh()
@flx.manager.reaction('connections_changed')
def update_number_of_connections(self, *events):
n = 0
for name in flx.manager.get_app_names():
sessions = flx.manager.get_connections(name)
n += len(sessions)
self.set_number_of_connections(n)
@flx.emitter
def system_info(self):
return dict(cpu=psutil.cpu_percent(),
mem=psutil.virtual_memory().percent,
sessions=self.number_of_connections,
total_sessions=flx.manager.total_sessions,
)
def refresh(self):
self.system_info()
asyncio.get_event_loop().call_later(1, self.refresh)
# Create global relay
relay = Relay()
class Monitor(flx.PyWidget):
cpu_count = psutil.cpu_count()
nsamples = nsamples
def init(self):
with flx.VBox():
flx.Label(html='<h3>Server monitor</h3>')
if flx.current_server().serving[0] == 'localhost':
# Don't do this for a public server
self.button = flx.Button(text='Do some work')
self.button.reaction(self._do_work, 'pointer_down')
self.view = MonitorView(flex=1)
@relay.reaction('system_info') # note that we connect to relay
def _push_info(self, *events):
if not self.session.status:
return relay.disconnect('system_info:' + self.id)
for ev in events:
self.view.update_info(dict(cpu=ev.cpu,
mem=ev.mem,
sessions=ev.sessions,
total_sessions=ev.total_sessions))
def _do_work(self, *events):
etime = time() + len(events)
# print('doing work for %i s' % len(events))
while time() < etime:
pass
class MonitorView(flx.VBox):
def init(self):
self.start_time = time()
self.status = flx.Label(text='...')
self.cpu_plot = flx.PlotWidget(flex=1, style='width: 640px; height: 320px;',
xdata=[], yrange=(0, 100),
ylabel='CPU usage (%)')
self.mem_plot = flx.PlotWidget(flex=1, style='width: 640px; height: 320px;',
xdata=[], yrange=(0, 100),
ylabel='Mem usage (%)')
@flx.action
def update_info(self, info):
# Set connections
n = info.sessions, info.total_sessions
self.status.set_html('There are %i connected clients.<br />' % n[0] +
'And in total we served %i connections.<br />' % n[1])
# Prepare plots
times = list(self.cpu_plot.xdata)
times.append(time() - self.start_time)
times = times[-self.nsamples:]
# cpu data
usage = list(self.cpu_plot.ydata)
usage.append(info.cpu)
usage = usage[-self.nsamples:]
self.cpu_plot.set_data(times, usage)
# mem data
usage = list(self.mem_plot.ydata)
usage.append(info.mem)
usage = usage[-self.nsamples:]
self.mem_plot.set_data(times, usage)
if __name__ == '__main__':
a = flx.App(Monitor)
a.serve()
# m = a.launch('browser') # for use during development
flx.start()
|