sysmon-ws/server.py
2013-07-18 11:53:26 +03:00

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()