From 22185654ac3b98ec0153d32e5cc6287ba6839ad2 Mon Sep 17 00:00:00 2001 From: Florian N Date: Fri, 14 Feb 2014 16:35:51 -0500 Subject: [PATCH] add disk read/writes, v1.2 --- LICENSE.md | 2 +- main/views.py | 46 +++++++++++++ pydash/settings.py | 2 +- pydash/urls.py | 2 +- static/css/dashboard.css | 17 ++++- templates/main.html | 88 ++++++++++++++++++------- usage/views.py | 139 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 268 insertions(+), 28 deletions(-) diff --git a/LICENSE.md b/LICENSE.md index 42e9839..06763cd 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014 Florian Neagu +Copyright (c) 2014 Florian Neagu - michaelneagu@gmail.com - https://github.com/k3oni/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/main/views.py b/main/views.py index 90f7cb0..9e79bea 100755 --- a/main/views.py +++ b/main/views.py @@ -1,3 +1,25 @@ +#The MIT License (MIT) +# +#Copyright (c) 2014 Florian Neagu - michaelneagu@gmail.com - https://github.com/k3oni/ +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. + import socket, platform, os, multiprocessing, json from datetime import timedelta @@ -179,6 +201,29 @@ def get_disk(): return data +def get_disk_rw(): + """ + Get the disk reads and writes + """ + try: + pipe = os.popen("cat /proc/partitions | grep -v 'major' | awk '{print $4}'") + data = pipe.read().strip().split('\n') + pipe.close() + + for i in data: + if i.isalpha(): + data = [] + pipe = os.popen("cat /proc/diskstats | grep -w '" + i + "'|awk '{print $4, $8}'") + rw = pipe.read().strip().split() + pipe.close() + + data.append([i, rw[0], rw[1]]) + + except Exception,err: + data = str(err) + + return data + def get_mem(): """ Get memory usage @@ -251,6 +296,7 @@ def getall(request): return render_to_response('main.html', {'gethostname': get_hostname(), 'getplatform': get_platform(), 'getcpus': get_cpus(), + 'getdiskrw': get_disk_rw(), 'time_refresh': time_refresh, 'time_refresh_long': time_refresh_long, 'time_refresh_net': time_refresh_net, diff --git a/pydash/settings.py b/pydash/settings.py index 4b564c6..4e56a0a 100644 --- a/pydash/settings.py +++ b/pydash/settings.py @@ -36,7 +36,7 @@ TIME_JS_REFRESH = 30000 TIME_JS_REFRESH_LONG = 120000 TIME_JS_REFRESH_NET = 2000 -VERSION = 1.1 +VERSION = 1.2 ALLOWED_HOSTS = ['*'] diff --git a/pydash/urls.py b/pydash/urls.py index f08a0be..4ef5663 100644 --- a/pydash/urls.py +++ b/pydash/urls.py @@ -16,13 +16,13 @@ urlpatterns = patterns('', url(r'^main/$', 'main.views.getall', name='main'), url(r'^info/uptime/$', 'usage.views.uptime', name='uptime'), url(r'^info/memory/$', 'usage.views.memusage', name='memusage'), - url(r'^info/users/$', 'usage.views.getusers', name='getusers'), url(r'^info/cpuusage/$', 'usage.views.cpuusage', name='cpuusage'), url(r'^info/getdisk/$', 'usage.views.getdisk', name='getdisk'), url(r'^info/getusers/$', 'usage.views.getusers', name='getusers'), url(r'^info/getips/$', 'usage.views.getips', name='getips'), url(r'^info/gettraffic/$', 'usage.views.gettraffic', name='gettraffic'), url(r'^info/proc/$', 'usage.views.getproc', name='getproc'), + url(r'^info/getdiskio/$', 'usage.views.getdiskio', name='getdiskio'), url(r'^info/loadaverage/$', 'usage.views.loadaverage', name='loadaverage') ) diff --git a/static/css/dashboard.css b/static/css/dashboard.css index 337845c..b0b44ab 100644 --- a/static/css/dashboard.css +++ b/static/css/dashboard.css @@ -388,4 +388,19 @@ h6.bigstats { padding: 0 0.3em; border-style: solid; } - +.diskr { + border-color: rgb(245,134,15); + margin: 0.5em; + border-style: solid; + border-width: 0 0 0 1em; + padding: 0 0.3em; + border-style: solid; +} +.diskw { + border-color: rgb(15,103,245); + margin: 0.5em; + border-style: solid; + border-width: 0 0 0 1em; + padding: 0 0.3em; + border-style: solid; +} diff --git a/templates/main.html b/templates/main.html index 8323d15..9be9b94 100644 --- a/templates/main.html +++ b/templates/main.html @@ -200,58 +200,83 @@ + +
-
+
-

IP Adresses

-
+

Internet Traffic

+
- - - - - - - - - - -
IntfIPMac
+

+ +
+ {% trans "In" %} + {% trans "Out" %} +
+
- +
-

Internet Traffic

-
+

Disk Reads/Writes

+

- +
- {% trans "In" %} - {% trans "Out" %} + {% trans "Reads" %} + {% trans "Writes" %}
-
-
- - +
+
+
+
+
+
+

IP Adresses

+
+
+
+ +
+ + + + + + + + + + +
IntfIPMac
+
+ +
+ +
+
+ +
@@ -412,6 +437,19 @@ var trf_ctx = $("#trfChart").get(0).getContext("2d"); trfChart.Line(data, options); }); } + +var dsk_ctx = $("#dskChart").get(0).getContext("2d"); + var dskChart = new Chart(dsk_ctx); + function disk_io(){ + $.getJSON('/info/getdiskio/', function(data) { + var options = { + animation : false, + pointDotRadius : 2, + scaleLabel : "<%=value%>" + } + dskChart.Line(data, options); + }); + } var load_ctx = $("#loadChart").get(0).getContext("2d"); var loadChart = new Chart(load_ctx); @@ -432,6 +470,7 @@ $(function() { window.setInterval('load_average()', {{ time_refresh }}); window.setInterval('cpuu_usage()', {{ time_refresh }}); window.setInterval('traffic_usage()', {{ time_refresh_net }}); + window.setInterval('disk_io()', {{ time_refresh_net }}); window.setInterval('dashboard.getUptime()', {{ time_refresh_long }}); window.setInterval('dashboard.getDisk()', {{ time_refresh_long }}); window.setInterval('dashboard.getUsers()', {{ time_refresh_long }}); @@ -443,6 +482,7 @@ $(function pageLoad() { load_average(); cpuu_usage(); traffic_usage(); + disk_io(); dashboard.getUptime(); dashboard.getDisk(); dashboard.getUsers(); diff --git a/usage/views.py b/usage/views.py index 150be81..92a528a 100755 --- a/usage/views.py +++ b/usage/views.py @@ -1,3 +1,25 @@ +#The MIT License (MIT) +# +#Copyright (c) 2014 Florian Neagu - michaelneagu@gmail.com - https://github.com/k3oni/ +# +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: +# +#The above copyright notice and this permission notice shall be included in all +#copies or substantial portions of the Software. +# +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +#SOFTWARE. + import json from django.shortcuts import render_to_response from django.http import HttpResponse, HttpResponseRedirect @@ -365,3 +387,120 @@ def gettraffic(request): response.write(data) return response + +@login_required(login_url='/login/') +def getdiskio(request): + """ + Return the reads and writes for the drive + """ + datasets_in = [] + datasets_in_i = [] + datasets_out = [] + datasets_out_o = [] + json_diskrw = [] + cookie_diskrw = {} + + try: + diskrw = get_disk_rw() + diskrw = diskrw[0] + + except Exception: + diskrw = 0 + + try: + cookies = request._cookies['diskrw'] + except Exception: + cookies = None + + if not cookies: + datasets_in.append(0) + datasets_in_i.append(0) + datasets_out.append(0) + datasets_out_o.append(0) + else: + datasets = eval(cookies) + datasets_in = datasets[0] + datasets_out = datasets[1] + datasets_in_i = datasets[2] + datasets_out_o = datasets[3] + + if len(datasets_in) > 10: + while datasets_in: + del datasets_in[0] + if len(datasets_in) == 10: + break + if len(datasets_in_i) > 2: + while datasets_in_i: + del datasets_in_i[0] + if len(datasets_in_i) == 2: + break + if len(datasets_out) > 10: + while datasets_out: + del datasets_out[0] + if len(datasets_out) == 10: + break + if len(datasets_out_o) > 2: + while datasets_out_o: + del datasets_out_o[0] + if len(datasets_out_o) == 2: + break + + if len(datasets_in_i) <= 1: + datasets_in_i.append(int(diskrw[1])) + if len(datasets_in_i) == 2: + datasets_in_i.append(int(diskrw[1])) + del datasets_in_i[0] + if len(datasets_out_o) <= 1: + datasets_out_o.append(int(diskrw[2])) + if len(datasets_out_o) == 2: + datasets_out_o.append(int(diskrw[2])) + del datasets_out_o[0] + + dataset_in = (int((datasets_in_i[1] - datasets_in_i[0]) / ( time_refresh_net / 1000 ))) + dataset_out = (int((datasets_out_o[1] - datasets_out_o[0]) / ( time_refresh_net / 1000 ))) + + if len(datasets_in) <= 9: + datasets_in.append(dataset_in) + if len(datasets_in) == 10: + datasets_in.append(dataset_in) + del datasets_in[0] + if len(datasets_out) <= 9: + datasets_out.append(dataset_out) + if len(datasets_out) == 10: + datasets_out.append(dataset_out) + del datasets_out[0] + + # Some fix division by 0 Chart.js + if len(datasets_in) == 10: + if sum(datasets_in) == 0: + datasets_in[9] += 0.1 + if sum(datasets_in) / 10 == datasets_in[0]: + datasets_in[9] += 0.1 + + disk_rw = { + 'labels': [""] * 10, + 'datasets': [ + { + "fillColor": "rgba(245,134,15,0.5)", + "strokeColor": "rgba(245,134,15,1)", + "pointColor": "rgba(245,134,15,1)", + "pointStrokeColor": "#fff", + "data": datasets_in + }, + { + "fillColor": "rgba(15,103,245,0.5)", + "strokeColor": "rgba(15,103,245,1)", + "pointColor": "rgba(15,103,245,1)", + "pointStrokeColor": "#fff", + "data": datasets_out + } + ] + } + + cookie_diskrw = [datasets_in, datasets_out, datasets_in_i, datasets_out_o] + data = json.dumps(disk_rw) + response = HttpResponse() + response['Content-Type'] = "text/javascript" + response.cookies['diskrw'] = cookie_diskrw + response.write(data) + return response