167 lines
4.8 KiB
Python
167 lines
4.8 KiB
Python
###############################################################################
|
|
##
|
|
## Copyright 2011,2012 Tavendo GmbH
|
|
##
|
|
## Licensed under the Apache License, Version 2.0 (the "License");
|
|
## you may not use this file except in compliance with the License.
|
|
## You may obtain a copy of the License at
|
|
##
|
|
## http://www.apache.org/licenses/LICENSE-2.0
|
|
##
|
|
## Unless required by applicable law or agreed to in writing, software
|
|
## distributed under the License is distributed on an "AS IS" BASIS,
|
|
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
## See the License for the specific language governing permissions and
|
|
## limitations under the License.
|
|
##
|
|
##
|
|
## Modified by Mikko Ahlroth, 2013
|
|
## Original is part of AutobahnPython and can be found at
|
|
## https://github.com/tavendo/AutobahnPython/blob/master/examples/websocket/broadcast/server.py
|
|
## Modifications are licensed with the MIT License, see LICENSE for details.
|
|
##
|
|
###############################################################################
|
|
|
|
import sys
|
|
import json
|
|
import psutil
|
|
|
|
from twisted.internet import reactor
|
|
from twisted.python import log
|
|
|
|
from autobahn.websocket import WebSocketServerFactory, \
|
|
WebSocketServerProtocol, \
|
|
listenWS
|
|
|
|
TICK_INTERVAL = 2
|
|
CPU_INTERVAL = 1
|
|
WEBSOCKET = 'ws://localhost:8081/'
|
|
NET_INTERFACE = 'eth0'
|
|
|
|
INITIAL_INFO = {
|
|
'cpus': psutil.NUM_CPUS,
|
|
'boot': psutil.get_boot_time(),
|
|
'version': '0.1',
|
|
}
|
|
|
|
|
|
def get_sys_status():
|
|
cpu = psutil.cpu_percent(interval=CPU_INTERVAL, percpu=True)
|
|
mem = psutil.virtual_memory().percent
|
|
swap = psutil.swap_memory().percent
|
|
procs = len(psutil.get_pid_list())
|
|
ct = psutil.cpu_times_percent()
|
|
cpu_times = {
|
|
'user': ct[0],
|
|
'system': ct[1],
|
|
'idle': ct[2],
|
|
'nice': ct[3],
|
|
'iowait': ct[4],
|
|
'irq': ct[5],
|
|
'softirq': ct[6],
|
|
'steal': ct[7],
|
|
'guest': ct[8],
|
|
'guest_nice': ct[9],
|
|
}
|
|
net = psutil.network_io_counters(pernic=True)[NET_INTERFACE]
|
|
net_out = {
|
|
'bytes_out': net.bytes_sent,
|
|
'bytes_in': net.bytes_recv,
|
|
}
|
|
disk = psutil.disk_io_counters()
|
|
disk_out = {
|
|
'read_count': disk.read_count,
|
|
'write_count': disk.write_count,
|
|
}
|
|
|
|
users = len(psutil.get_users())
|
|
|
|
return {
|
|
'cpu': cpu,
|
|
'mem': mem,
|
|
'swap': swap,
|
|
'procs': procs,
|
|
'cpu_times': cpu_times,
|
|
'net': net_out,
|
|
'disk': disk_out,
|
|
'users': users,
|
|
}
|
|
|
|
|
|
|
|
class BroadcastServerProtocol(WebSocketServerProtocol):
|
|
|
|
def onOpen(self):
|
|
self.factory.register(self)
|
|
|
|
def onMessage(self, msg, binary):
|
|
pass
|
|
|
|
def connectionLost(self, reason):
|
|
WebSocketServerProtocol.connectionLost(self, reason)
|
|
self.factory.unregister(self)
|
|
|
|
|
|
class BroadcastServerFactory(WebSocketServerFactory):
|
|
|
|
def __init__(self, url, debug=False, debugCodePaths=False):
|
|
WebSocketServerFactory.__init__(self, url, debug=debug, debugCodePaths=debugCodePaths)
|
|
self.clients = []
|
|
self.tick()
|
|
|
|
def tick(self):
|
|
self.broadcast(json.dumps(get_sys_status()))
|
|
reactor.callLater(TICK_INTERVAL - CPU_INTERVAL, self.tick)
|
|
|
|
def register(self, client):
|
|
if not client in self.clients:
|
|
print "registered client " + client.peerstr
|
|
self.clients.append(client)
|
|
client.sendMessage(json.dumps(INITIAL_INFO))
|
|
|
|
def unregister(self, client):
|
|
if client in self.clients:
|
|
print "unregistered client " + client.peerstr
|
|
self.clients.remove(client)
|
|
|
|
def broadcast(self, msg):
|
|
print "broadcasting message '%s' .." % msg
|
|
for c in self.clients:
|
|
c.sendMessage(msg)
|
|
print "message sent to " + c.peerstr
|
|
|
|
|
|
class BroadcastPreparedServerFactory(BroadcastServerFactory):
|
|
"""
|
|
Functionally same as above, but optimized broadcast using
|
|
prepareMessage and sendPreparedMessage.
|
|
"""
|
|
|
|
def broadcast(self, msg):
|
|
print "broadcasting prepared message '%s' .." % msg
|
|
preparedMsg = self.prepareMessage(msg)
|
|
for c in self.clients:
|
|
c.sendPreparedMessage(preparedMsg)
|
|
print "prepared message sent to " + c.peerstr
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
|
|
log.startLogging(sys.stdout)
|
|
debug = True
|
|
else:
|
|
debug = False
|
|
|
|
#ServerFactory = BroadcastServerFactory
|
|
ServerFactory = BroadcastPreparedServerFactory
|
|
|
|
factory = ServerFactory(WEBSOCKET,
|
|
debug=debug,
|
|
debugCodePaths=debug)
|
|
|
|
factory.protocol = BroadcastServerProtocol
|
|
factory.setProtocolOptions(allowHixie76=True)
|
|
listenWS(factory)
|
|
|
|
reactor.run()
|