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
*.css
*.js *.js
*.swp
ALL := style.css scripts.js ALL := scripts.js
.PHONY: all .PHONY: all
all: $(ALL) all: $(ALL)
%.css: %.sass
sass --no-cache $< | yui-compressor --type css --output $@
%.js: %.coffee %.js: %.coffee
coffee --compile --output $(@D) $< 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 @@ ...@@ -3,8 +3,37 @@
<head> <head>
<title>PcTaddeus monitor</title> <title>PcTaddeus monitor</title>
<link href="style.css" type="text/css" rel="stylesheet"> <link href="style.css" type="text/css" rel="stylesheet">
<link href="font-awesome.min.css" type="text/css" rel="stylesheet">
</head> </head>
<body> <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> <script src="scripts.js" type="text/javascript"></script>
</body> </body>
</html> </html>
ws = new WebSocket('ws://localhost:12345') el = (id) -> document.getElementById(id)
#ws = new WebSocket('ws://80.56.96.111:12345') set = (id, value) -> el(id).innerHTML = value
ws.onopen = -> console.log 'open' values = (e for e in el('content').getElementsByTagName('span')) \
ws.onclose = -> console.log 'close' .concat(el('release'))
ws.onerror = (e) -> console.log 'error', e
ws.onmessage = (msg) -> console.log 'msg', msg.data connect = ->
#ws.onmessage = (msg) -> console.log 'msg', JSON.parse(msg.data) 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 @@ ...@@ -2,37 +2,68 @@
import time import time
import socket import socket
import json import json
import subprocess
import re import re
from subprocess import check_output
from threading import Thread 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: with open('/proc/uptime', 'r') as f:
uptime, idletime = map(float, f.read().split(' ')) 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'): if m:
m = re.match(r'^Core \d+:\s*\+(\d+\.\d+)', line) temps.append(float(m.group(1)))
if m: yield 'temps', temps
temps.append(float(m.group(1))) 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 = { # Memory usage
'uptime': uptime, with open('/proc/meminfo', 'r') as f:
'temps': temps, for line in f.readlines():
'cpu_usage': max(round(100 - cpu_idle, 2), 0) 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__': if __name__ == '__main__':
server = websocket() server = websocket(extensions=[WebkitDeflateFrame()])
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('', 12345)) server.bind(('', 12345))
server.listen(5) server.listen(5)
...@@ -50,17 +81,19 @@ if __name__ == '__main__': ...@@ -50,17 +81,19 @@ if __name__ == '__main__':
try: try:
while True: while True:
if len(clients): if not clients:
status = status_message() time.sleep(6)
#time.sleep(.1)
for client in list(clients): continue
try:
client.send(status.frame()) status = Frame(OPCODE_TEXT, json.dumps(dict(stats())))
except socket.error:
print 'Client disconnected' for client in list(clients):
clients.remove(client) try:
else: client.send(status)
time.sleep(5) except socket.error:
print 'Client disconnected'
clients.remove(client)
time.sleep(1) time.sleep(1)
except KeyboardInterrupt: 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 ...@@ -6,7 +6,7 @@ make
while true; do while true; do
inotifywait --quiet --exclude \.swp\$ --event moved_to,attrib,modify \ inotifywait --quiet --exclude \.swp\$ --event moved_to,attrib,modify \
. *.sass *.coffee *.coffee
sleep 0.05s sleep 0.05s
make make
done 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