summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2013-04-14 15:08:25 -0500
committerDan McGee <dan@archlinux.org>2013-04-14 15:08:25 -0500
commit9b07cb1ebdc8c5cc5dff66a7edb02e0ddc9f4733 (patch)
tree438a53173e4fd3e33ec8bb3ff60fda836bd1b7c2
parente4e88638b68ca34cc15ea5551f0e8a1a4c2e03d5 (diff)
Draw one mirror status graph per check location
Rather than lump it all together and have odd spikes depending on which side of the Atlantic checked a mirror in a given timeslot, draw a chart per check location. Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r--mirrors/static/mirror_status.js68
-rw-r--r--mirrors/views.py3
-rw-r--r--templates/mirrors/mirror_details.html12
3 files changed, 60 insertions, 23 deletions
diff --git a/mirrors/static/mirror_status.js b/mirrors/static/mirror_status.js
index 8ec85c40..4a57128a 100644
--- a/mirrors/static/mirror_status.js
+++ b/mirrors/static/mirror_status.js
@@ -1,7 +1,16 @@
-function mirror_status(chart_id, data_url) {
- var jq_div = jQuery(chart_id);
+function draw_graphs(location_url, log_url, container_id) {
+ $.when($.getJSON(location_url), $.getJSON(log_url))
+ .then(function(loc_data, log_data) {
+ $.each(loc_data[0].locations, function(i, val) {
+ mirror_status(container_id, val, log_data[0]);
+ });
+ });
+}
- var draw_graph = function(data) {
+function mirror_status(container_id, check_loc, log_data) {
+
+ var draw_graph = function(chart_id, data) {
+ var jq_div = jQuery(chart_id);
var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = jq_div.width() - margin.left - margin.right,
height = jq_div.height() - margin.top - margin.bottom;
@@ -106,31 +115,52 @@ function mirror_status(chart_id, data_url) {
.text(function(d) { return d; });
};
- /* invoke the data-fetch + first draw */
- var cached_data = null;
- d3.json(data_url, function(json) {
- cached_data = jQuery.map(json.urls, function(url, i) {
+ var filter_data = function(json, location_id) {
+ return jQuery.map(json.urls, function(url, i) {
+ var logs = jQuery.map(url.logs, function(log, j) {
+ if (!log.is_success) {
+ return null;
+ }
+ /* screen by location ID if we were given one */
+ if (location_id && log.location_id !== location_id) {
+ return null;
+ }
+ return {
+ duration: log.duration,
+ check_time: new Date(log.check_time)
+ };
+ });
+ /* don't return URLs without any log info */
+ if (logs.length === 0) {
+ return null;
+ }
return {
url: url.url,
- logs: jQuery.map(url.logs, function(log, j) {
- if (!log.is_success) {
- return null;
- }
- return {
- duration: log.duration,
- check_time: new Date(log.check_time)
- };
- })
+ logs: logs
};
});
- draw_graph(cached_data);
- });
+ };
+
+ var cached_data = filter_data(log_data, check_loc.id);
+ /* we had a check location with no log data handed to us, skip graphing */
+ if (cached_data.length === 0) {
+ return;
+ }
+
+ /* create the containers, defer the actual graph drawing */
+ var chart_id = 'status-chart-' + check_loc.id;
+ $(container_id).append('<h3><span class="fam-flag fam-flag-' + check_loc.country_code.toLowerCase() + '" title="' + check_loc.country + '"></span> ' + check_loc.country + ' (' + check_loc.source_ip + '), IPv' + check_loc.ip_version + '</h3>');
+ $(container_id).append('<div id="' + chart_id + '" class="visualize-mirror visualize-chart"></div>');
+ $(container_id).append('<br/>');
+ setTimeout(function() {
+ draw_graph('#' + chart_id, cached_data);
+ }, 0);
/* then hook up a resize handler to redraw if necessary */
var resize_timeout = null;
var real_resize = function() {
resize_timeout = null;
- draw_graph(cached_data);
+ draw_graph('#' + chart_id, cached_data);
};
jQuery(window).resize(function() {
if (resize_timeout) {
diff --git a/mirrors/views.py b/mirrors/views.py
index 30f96b63..9311fb8f 100644
--- a/mirrors/views.py
+++ b/mirrors/views.py
@@ -304,6 +304,7 @@ class LocationJSONEncoder(DjangoJSONEncoder):
return list(obj)
if isinstance(obj, CheckLocation):
return {
+ 'id': obj.pk,
'hostname': obj.hostname,
'source_ip': obj.source_ip,
'country': unicode(obj.country.name),
@@ -316,7 +317,7 @@ class LocationJSONEncoder(DjangoJSONEncoder):
def locations_json(request):
data = {}
data['version'] = 1
- data['locations'] = CheckLocation.objects.all()
+ data['locations'] = CheckLocation.objects.all().order_by('pk')
to_json = json.dumps(data, ensure_ascii=False, cls=LocationJSONEncoder)
response = HttpResponse(to_json, content_type='application/json')
return response
diff --git a/templates/mirrors/mirror_details.html b/templates/mirrors/mirror_details.html
index ee60157b..1c9a970e 100644
--- a/templates/mirrors/mirror_details.html
+++ b/templates/mirrors/mirror_details.html
@@ -106,10 +106,16 @@
{% endfor %}
</tbody>
</table>
+</div>
+
+<div class="box">
+ <h2>Mirror Status Charts</h2>
- <h3>Mirror Status Chart</h3>
+ <p>Periodic checks of the mirrors are done from various geographic
+ locations, IP addresses, and using IPv4 or IPv6. These results are
+ summarized in graphical form below.</p>
- <div id="visualize-mirror" class="visualize-mirror visualize-chart"></div>
+ <div id="charts-container"></div>
</div>
{% load cdn %}{% jquery %}{% jquery_tablesorter %}
<script type="text/javascript" src="{% static "d3-3.0.6.min.js" %}"></script>
@@ -122,7 +128,7 @@ $(document).ready(function() {
headers: { 8: { sorter: 'mostlydigit' }, 9: { sorter: 'mostlydigit' }, 10: { sorter: 'mostlydigit' } } });
});
$(document).ready(function() {
- mirror_status("#visualize-mirror", "./json/");
+ draw_graphs("/mirrors/locations/json/", "./json/", "#charts-container");
});
</script>
{% endblock %}