Commit 1acdcc82 authored by Taddeüs Kroes's avatar Taddeüs Kroes

Created GUI, added more stats, client now reconnects after disconnect, code cleanup

parent a4cdc6bc
ALL := style.css scripts.js
ALL := scripts.js
.PHONY: all
all: $(ALL)
%.css: %.sass
sass --no-cache $< | yui-compressor --type css --output $@
%.js: %.coffee
coffee --compile --output $(@D) $<
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -3,8 +3,37 @@
<head>
<title>PcTaddeus monitor</title>
<link href="style.css" type="text/css" rel="stylesheet">
<link href="font-awesome.min.css" type="text/css" rel="stylesheet">
</head>
<body>
<div class="header">
<div class="center">
<i class="icon-gear"></i><span id="release">-</span>
<span id="status" class="right"></span>
</div>
</div>
<div id="content" class="center">
<div>
<i class="icon-time"></i>Uptime:
<span id="uptime" class="right">-</span>
</div>
<div>
<i class="icon-fire"></i>CPU Core temperatures:
<span id="temp" class="right">-</span>
</div>
<div>
<i class="icon-dashboard"></i>CPU usage:
<span id="cpu-usage" class="right">-</span>
</div>
<div>
<i class="icon-tasks"></i>Memory usage:
<span id="memory" class="right">-</span>
</div>
<div>
<i class="icon-hdd"></i>Disk usage:
<span id="disk" class="right">-</span>
</div>
</div>
<script src="scripts.js" type="text/javascript"></script>
</body>
</html>
ws = new WebSocket('ws://localhost:12345')
#ws = new WebSocket('ws://80.56.96.111:12345')
ws.onopen = -> console.log 'open'
ws.onclose = -> console.log 'close'
ws.onerror = (e) -> console.log 'error', e
ws.onmessage = (msg) -> console.log 'msg', msg.data
#ws.onmessage = (msg) -> console.log 'msg', JSON.parse(msg.data)
el = (id) -> document.getElementById(id)
set = (id, value) -> el(id).innerHTML = value
values = (e for e in el('content').getElementsByTagName('span')) \
.concat(el('release'))
connect = ->
val.innerHTML = 'Connecting...' for val in values
ws = new WebSocket 'ws://localhost:12345'
ws.onopen = ->
console.log 'open'
el('status').className = 'right online'
set('status', '<i class="icon-off"></i>Online')
ws.onclose = ->
console.log 'close'
val.innerHTML = '-' for val in values
el('status').className = 'right offline'
set('status', '<i class="icon-off"></i>Offline')
setTimeout connect, 5000
ws.onerror = (e) ->
console.log 'error', e
ws.onmessage = (msg) ->
console.log 'msg', msg.data
data = JSON.parse(msg.data)
set('release', data.os) if data.os
set('uptime', fmt_time(data.uptime)) if data.uptime
if data.temps.length
el('temp').innerHTML = ("#{deg}&#8451;" for deg in data.temps) \
.join('&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;')
set('cpu-usage', "#{data.cpu_usage}%") if data.cpu_usage
set('memory', fmt_kbytes_usage(data.memory)) if data.memory
set('disk', fmt_kbytes_usage(data.disk)) if data.disk
fmt_time = (total) ->
total = Math.round total
s = (n) -> if n == 1 then '' else 's'
secs = total % 60
str = "#{secs} second" + s(secs)
if total >= 60
mins = parseInt total % (60 * 60) / 60
str = "#{mins} minute#{s(mins)}, #{str}"
if total >= 60 * 60
hours = parseInt total % (60 * 60 * 24) / (60 * 60)
str = "#{hours} hour#{s(hours)}, #{str}"
str
fmt_kbytes_usage = ([used, total]) ->
used = Math.round used / 1000
total = Math.round total / 1000
perc = Math.round used / total * 100
return "#{used}MB / #{total}MB (#{perc}%)"
connect()
......@@ -2,37 +2,68 @@
import time
import socket
import json
import subprocess
import re
from subprocess import check_output
from threading import Thread
from twspy import websocket, TextMessage
from twspy import websocket, Frame, OPCODE_TEXT, WebkitDeflateFrame
def status_message():
def stats():
# Release
dist, codename = check_output(['lsb_release', '-sdc']).rstrip().split('\n')
yield 'release', '%s (%s)' % (dist, codename)
# Uptime
with open('/proc/uptime', 'r') as f:
uptime, idletime = map(float, f.read().split(' '))
yield 'uptime', uptime
# CPU temperature
try:
temps = []
temps = []
for line in check_output('sensors').split('\n'):
m = re.match(r'^Core \d+:\s*\+(\d+\.\d+)', line)
for line in subprocess.check_output('sensors').split('\n'):
m = re.match(r'^Core \d+:\s*\+(\d+\.\d+)', line)
if m:
temps.append(float(m.group(1)))
if m:
temps.append(float(m.group(1)))
yield 'temps', temps
except:
pass
cpu_idle = float(subprocess.check_output('mpstat').rsplit(' ', 1)[-1])
# CPU usage
with open('/proc/stat', 'r') as f:
line = f.readlines()[0].rstrip().split()
assert line[0] == 'cpu'
numbers = map(int, line[1:])
total = sum(numbers)
idle = numbers[3]
yield 'cpu_usage', round(float(total - idle) / total * 100, 2)
data = {
'uptime': uptime,
'temps': temps,
'cpu_usage': max(round(100 - cpu_idle, 2), 0)
}
# Memory usage
with open('/proc/meminfo', 'r') as f:
for line in f.readlines():
if line.startswith('MemTotal'):
assert line.endswith('kB\n')
total = int(line.split()[1])
elif line.startswith('MemFree'):
assert line.endswith('kB\n')
used = total - int(line.split()[1])
yield 'memory', (used, total)
break
return TextMessage(json.dumps(data))
# Disk usage
for line in check_output('df').split('\n'):
parts = line.split()
if parts[0].startswith('/dev/') and parts[5] == '/':
used, avail = map(int, parts[2:4])
yield 'disk', (used, used + avail)
break
if __name__ == '__main__':
server = websocket()
server = websocket(extensions=[WebkitDeflateFrame()])
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', 12345))
server.listen(5)
......@@ -50,17 +81,19 @@ if __name__ == '__main__':
try:
while True:
if len(clients):
status = status_message()
for client in list(clients):
try:
client.send(status.frame())
except socket.error:
print 'Client disconnected'
clients.remove(client)
else:
time.sleep(5)
if not clients:
time.sleep(6)
#time.sleep(.1)
continue
status = Frame(OPCODE_TEXT, json.dumps(dict(stats())))
for client in list(clients):
try:
client.send(status)
except socket.error:
print 'Client disconnected'
clients.remove(client)
time.sleep(1)
except KeyboardInterrupt:
......
body {
background-color: #efefef;
font-family: Arial;
font-size: 16px;
margin: 0;
padding: 0;
}
.header {
background-color: #111;
width: 100%;
color: #fff;
padding: 10px 0;
}
.header .center {
width: 550px;
}
#status { font-weight :bold; }
#status.offline { color: #E61212; }
#status.online { color: #3CE01B; }
.center {
margin-left: auto;
margin-right: auto;
}
#content {
width: 500px;
margin-top: 30px;
padding: 10px 25px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
line-height: 40px;
}
.right {
float: right;
}
[class^="icon-"] {
display: inline-block !important;
width: 23px !important;
/*margin-right: 7px;*/
}
body
background-color: #f1f1f1
......@@ -6,7 +6,7 @@ make
while true; do
inotifywait --quiet --exclude \.swp\$ --event moved_to,attrib,modify \
. *.sass *.coffee
*.coffee
sleep 0.05s
make
done
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment