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  | """
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
from flexx import app, ui, event
nsamples = 16
class Relay(event.HasEvents):
    def __init__(self):
        super().__init__()
        app.manager.connect(self._set_n_connections, 'connections_changed')
        self._set_n_connections()
        self.refresh()
    def _set_n_connections(self, *events):
        n = 0
        for name in app.manager.get_app_names():
            proxies = app.manager.get_connections(name)
            n += len(proxies)
        self._n_connections = n
        self.system_info()
    @event.emitter
    def system_info(self):
        return dict(cpu=psutil.cpu_percent(),
                    mem=psutil.virtual_memory().percent,
                    sessions=self._n_connections,
                    total_sessions=app.manager.total_sessions,
                    )
    def refresh(self):
        self.system_info()
        app.call_later(1, self.refresh)
# Create global relay
relay = Relay()
class Monitor(ui.Widget):
    def init(self):
        with ui.HBox():
            with ui.VBox():
                ui.Label(text='<h3>Server monitor</h3>')
                self.info = ui.Label(text='...')
                if app.current_server().serving[0] == 'localhost':
                    # Don't do this for a public server
                    self.button = ui.Button(text='Do some work')
                    self.button.connect('mouse_down', self._do_work)
                self.cpu_plot = ui.PlotWidget(style='width: 640px; height: 320px;',
                                              xdata=[], yrange=(0, 100),
                                              ylabel='CPU usage (%)',
                                              sync_props=False)
                self.mem_plot = ui.PlotWidget(style='width: 640px; height: 320px;',
                                              xdata=[], yrange=(0, 100),
                                              ylabel='Mem usage (%)',
                                              sync_props=False)
                ui.Widget(flex=1)
    @relay.connect('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)
        self.emit('system_info', events[-1])
    def _do_work(self, *events):
        etime = time() + len(events)
        while time() < etime:
            pass
    class JS:
        cpu_count = psutil.cpu_count()
        nsamples = nsamples
        def init(self):
            super().init()
            self.start_time = time()
        @event.connect('!system_info')
        def _update_info(self, *events):
            ev = events[-1]
            # Set connections
            n = ev.sessions, ev.total_sessions
            self.info.text = ('There are %i connected clients.<br />' % n[0] +
                              'And in total we served %i connections.<br />' % n[1])
            # Prepare plots
            times = self.cpu_plot.xdata.copy()
            times.append(time() - self.start_time)
            times = times[-self.nsamples:]
            self.cpu_plot.xdata = times
            self.mem_plot.xdata = times
            # cpu data
            usage = self.cpu_plot.ydata
            usage.append(ev.cpu)
            usage = usage[-self.nsamples:]
            self.cpu_plot.ydata = usage
            # mem data
            usage = self.mem_plot.ydata
            usage.append(ev.mem)
            usage = usage[-self.nsamples:]
            self.mem_plot.ydata = usage
if __name__ == '__main__':
    app.serve(Monitor)
    # m = app.launch(Monitor)  # for use during development
    app.start()
 
 |