first commit
This commit is contained in:
commit
364e6745d0
|
@ -0,0 +1,71 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pymongo
|
||||||
|
import cherrypy
|
||||||
|
import simplejson as json
|
||||||
|
import datetime
|
||||||
|
import os.path
|
||||||
|
import time
|
||||||
|
|
||||||
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
client = pymongo.MongoClient("localhost", 27017)
|
||||||
|
db = client.myping
|
||||||
|
|
||||||
|
class Values:
|
||||||
|
|
||||||
|
def index(self, **params):
|
||||||
|
return cherrypy.lib.static.serve_file(os.path.join(current_dir, 'public/index.html'))
|
||||||
|
|
||||||
|
def values(self, items, host, **params):
|
||||||
|
values = { 'ranges': [], 'values': [] }
|
||||||
|
|
||||||
|
for record in db.my_collection.find({"host": host}).sort('$natural', pymongo.DESCENDING).limit(int(items)):
|
||||||
|
dt = time.mktime(record['date'].timetuple()) * 1000
|
||||||
|
values['ranges'].append([dt, record['min'], record['max']])
|
||||||
|
values['values'].append([dt, record['avg']])
|
||||||
|
|
||||||
|
values['ranges'].reverse()
|
||||||
|
values['values'].reverse()
|
||||||
|
|
||||||
|
cherrypy.response.headers['Content-Type']= 'application/json'
|
||||||
|
return json.dumps(values)
|
||||||
|
|
||||||
|
def update(self, timestamp, host, **params):
|
||||||
|
values = { 'ranges': [], 'values': [] }
|
||||||
|
|
||||||
|
date = datetime.datetime.fromtimestamp(int(timestamp))
|
||||||
|
|
||||||
|
for record in db.my_collection.find({"host": host, 'date': {'$gt': date}}).sort('$natural', pymongo.DESCENDING).limit(100):
|
||||||
|
dt = time.mktime(record['date'].timetuple()) * 1000
|
||||||
|
values['ranges'].append([dt, record['min'], record['max']])
|
||||||
|
values['values'].append([dt, record['avg']])
|
||||||
|
|
||||||
|
values['ranges'].reverse()
|
||||||
|
values['values'].reverse()
|
||||||
|
|
||||||
|
cherrypy.response.headers['Content-Type']= 'application/json'
|
||||||
|
return json.dumps(values)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mapper = cherrypy.dispatch.RoutesDispatcher()
|
||||||
|
mapper.connect('home',"/",controller=Values(), action='index')
|
||||||
|
mapper.connect('values',"/api/values/:items/:host", controller=Values(), action='values')
|
||||||
|
mapper.connect('update',"/api/update/:timestamp/:host", controller=Values(), action='update')
|
||||||
|
|
||||||
|
cherrypy.tree.mount(None,config=
|
||||||
|
{
|
||||||
|
"/":
|
||||||
|
{
|
||||||
|
"request.dispatch": mapper,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
cherrypy.server.socket_host = '0.0.0.0'
|
||||||
|
cherrypy.engine.start()
|
||||||
|
cherrypy.engine.block()
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/usr/bin/env python2
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import pymongo
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
client = pymongo.MongoClient("localhost", 27017)
|
||||||
|
db = client.myping
|
||||||
|
|
||||||
|
hosts = [
|
||||||
|
"DeadBSD.org",
|
||||||
|
"nausea.DeadBSD.org",
|
||||||
|
"helvete.DeadBSD.org",
|
||||||
|
"gamito.DeadBSD.org",
|
||||||
|
"www.nos.pt",
|
||||||
|
"192.168.5.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
arguments = [
|
||||||
|
"fping",
|
||||||
|
"-C", "20",
|
||||||
|
"-q",
|
||||||
|
"-B1",
|
||||||
|
"-r1",
|
||||||
|
"-i10",
|
||||||
|
]
|
||||||
|
|
||||||
|
for h in hosts:
|
||||||
|
arguments.append(h)
|
||||||
|
|
||||||
|
dt = datetime.datetime.now()
|
||||||
|
|
||||||
|
p = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||||
|
output = p.communicate()[0]
|
||||||
|
|
||||||
|
for h in hosts:
|
||||||
|
obj = { 'date': dt, 'host': h }
|
||||||
|
match = re.search("" + h + " +: (.*)?", output)
|
||||||
|
if match:
|
||||||
|
result = match.group(1)
|
||||||
|
times = map(float, result.split())
|
||||||
|
obj['min'] = min(times)
|
||||||
|
obj['avg'] = sum(times) / float(len(times))
|
||||||
|
obj['max'] = max(times)
|
||||||
|
print obj
|
||||||
|
db.my_collection.insert_one(obj)
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
|
<meta name="googlebot" content="noindex, nofollow">
|
||||||
|
|
||||||
|
<script type="text/javascript" src="//code.jquery.com/jquery-3.1.1.js"></script>
|
||||||
|
|
||||||
|
<title></title>
|
||||||
|
|
||||||
|
<script type='text/javascript'>//<![CDATA[
|
||||||
|
|
||||||
|
function get_graph(host, container, values) {
|
||||||
|
var chart = Highcharts.chart(container, {
|
||||||
|
chart: {
|
||||||
|
type: 'spline',
|
||||||
|
zoomType: 'x',
|
||||||
|
animation: Highcharts.svg,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'ping ' + host
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'datetime',
|
||||||
|
dateTimeLabelFormats: { // don't display the dummy year
|
||||||
|
month: '%e. %b',
|
||||||
|
year: '%b'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Date'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
yAxis: {
|
||||||
|
title: {
|
||||||
|
text: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
tooltip: {
|
||||||
|
crosshairs: true,
|
||||||
|
shared: true,
|
||||||
|
valueSuffix: ' ms'
|
||||||
|
},
|
||||||
|
|
||||||
|
legend: {
|
||||||
|
},
|
||||||
|
|
||||||
|
series: [{
|
||||||
|
name: 'Average RTT',
|
||||||
|
//data: data['values'],
|
||||||
|
data: [],
|
||||||
|
zIndex: 1,
|
||||||
|
marker: {
|
||||||
|
fillColor: 'white',
|
||||||
|
lineWidth: 1,
|
||||||
|
lineColor: Highcharts.getOptions().colors[0]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: 'RTT Range',
|
||||||
|
//data: data['ranges'],
|
||||||
|
data: [],
|
||||||
|
type: 'arearange',
|
||||||
|
lineWidth: 0,
|
||||||
|
linkedTo: ':previous',
|
||||||
|
color: Highcharts.getOptions().colors[1],
|
||||||
|
fillOpacity: 0.2,
|
||||||
|
zIndex: 0
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
graph(chart, host, values);
|
||||||
|
|
||||||
|
return chart;
|
||||||
|
}
|
||||||
|
|
||||||
|
function graph(chart, host, values) {
|
||||||
|
$.get("/api/values/" + values + "/" + host, function(data) {
|
||||||
|
chart.series[0].setData(data['values']);
|
||||||
|
chart.series[1].setData(data['ranges']);
|
||||||
|
chart.redraw();
|
||||||
|
|
||||||
|
setTimeout(update, 60000, chart, host, values);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(chart, host, values) {
|
||||||
|
last = chart.series[0].points[chart.series[0].points.length - 1].x;
|
||||||
|
last = last / 1000;
|
||||||
|
|
||||||
|
//console.log(chart.series[0].points.length);
|
||||||
|
|
||||||
|
$.get("/api/update/"+ last + "/" + host, function(data) {
|
||||||
|
shift = false;
|
||||||
|
if (chart.series[0].points.length == values) {
|
||||||
|
shift = true;
|
||||||
|
}
|
||||||
|
for (i = 0; i < data['values'].length; i++) {
|
||||||
|
chart.series[0].addPoint(data['values'][i], false, shift);
|
||||||
|
chart.series[1].addPoint(data['ranges'][i], false, shift);
|
||||||
|
}
|
||||||
|
chart.redraw();
|
||||||
|
setTimeout(update, 60000, chart, host);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
var c1 = get_graph('DeadBSD.org', 'container1', 100);
|
||||||
|
var c2 = get_graph('nausea.DeadBSD.org', 'container2', 100);
|
||||||
|
var c3 = get_graph('helvete.DeadBSD.org', 'container3', 100);
|
||||||
|
var c4 = get_graph('gamito.DeadBSD.org', 'container4', 100);
|
||||||
|
var c5 = get_graph('www.nos.pt', 'container5', 100);
|
||||||
|
var c5 = get_graph('192.168.5.1', 'container6', 100);
|
||||||
|
});
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script src="https://code.highcharts.com/highcharts.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/highcharts-more.js"></script>
|
||||||
|
<script src="https://code.highcharts.com/modules/exporting.js"></script>
|
||||||
|
|
||||||
|
<div id="container1" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="container2" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="container3" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="container4" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="container5" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
<div id="container6" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue