Explorar o código

better scale, sort stacked areas

raylu %!s(int64=11) %!d(string=hai) anos
pai
achega
d76a5dd133
Modificáronse 2 ficheiros con 82 adicións e 31 borrados
  1. 10 7
      api/server.py
  2. 72 24
      web/static/js/stats.js

+ 10 - 7
api/server.py

@@ -139,15 +139,18 @@ def get_stats(split, query, environ):
 			elif field == 'mem':
 				# translate total to free, subtract buffers and cached from used
 				field_data = {}
-				for subfield in ['used', 'buffers', 'cached', 'free']:
+				new_fields = ['used', 'buffers', 'cached', 'free']
+				for subfield in new_fields:
 					field_data[subfield] = [None] * 1440
-				MB = 1024 * 1024
 				for i in xrange(1440):
-					field_data['free'][i] = (subfields['total'][i] - subfields['used'][i]) / MB
-					field_data['used'][i] = (subfields['used'][i] -
-							subfields['buffers'][i] - subfields['cached'][i]) / MB
-					field_data['buffers'][i] = subfields['buffers'][i] / MB
-					field_data['cached'][i] = subfields['cached'][i] / MB
+					if subfields['total'][i] == -1:
+						for nf in new_fields:
+							field_data[nf][i] = None
+						continue
+					field_data['free'][i] = subfields['total'][i] - subfields['used'][i]
+					field_data['used'][i] = subfields['used'][i] - subfields['buffers'][i] - subfields['cached'][i]
+					field_data['buffers'][i] = subfields['buffers'][i]
+					field_data['cached'][i] = subfields['cached'][i]
 				for subfield, array in field_data.items():
 					stats[field].setdefault(subfield, {})
 					stats[field][subfield][date] = array

+ 72 - 24
web/static/js/stats.js

@@ -1,6 +1,43 @@
 window.addEvent('domready', function() {
 	'use strict';
 
+	Rickshaw.Graph.Axis.Y.Base1024KMGTP = Rickshaw.Class.create(Rickshaw.Graph.Axis.Y, {
+		'_drawAxis': function($super, scale) {
+			var axis = d3.svg.axis().scale(scale).orient(this.orientation);
+			var domain = axis.scale().domain();
+			var tickSpacing = 1;
+			while (tickSpacing * 1024 < domain[1])
+				tickSpacing *= 1024;
+			while (tickSpacing * 20 < domain[1])
+				tickSpacing *= 10;
+			while (tickSpacing * 5 < domain[1])
+				tickSpacing *= 2;
+			var min = Math.ceil(domain[0] / tickSpacing);
+			var max = Math.floor(domain[1] / tickSpacing) + 1;
+			var tickValues = [];
+			for (var i = min * tickSpacing; i < max; i += 1)
+				tickValues.push(i * tickSpacing);
+			axis.tickValues(tickValues);
+			axis.tickFormat(this.tickFormat);
+
+			if (this.orientation == 'left') {
+				var berth = this.height * berthRate;
+				var transform = 'translate(' + this.width + ', ' + berth + ')';
+			}
+
+			if (this.element)
+				this.vis.selectAll('*').remove();
+
+			this.vis
+				.append('svg:g')
+				.attr('class', ['y_ticks', this.ticksTreatment].join(' '))
+				.attr('transform', transform)
+				.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));
+
+			return axis;
+		},
+	});
+
 	new Request.JSON({
 		'url': 'http://localhost:8892/v1/1/stats/1?start=2014-04-19&end=2014-04-19',
 		'onSuccess': graph_stats,
@@ -15,30 +52,40 @@ window.addEvent('domready', function() {
 	}
 
 	var colors = {
-		'cpu': {
-			'idle': '#3aa',
-			'user': '#33a',
-			'system': '#aa3',
-			'iowait': '#a33',
-		},
-		'mem': {
-			'free': '#3a3',
-			'used': '#a33',
-			'buffers': '#3aa',
-			'cached': '#33a',
-		},
-		'net': {
-			'bit/s_in': '#33a',
-			'bit/s_out': '#3a3',
-		},
+		'cpu': [
+			['user', '#33a'],
+			['nice', '#55c'],
+			['iowait', '#a33'],
+			['system', '#aa3'],
+			['irq', '#711'],
+			['softirq', '#771'],
+			['guest', '#555'],
+			['guest_nice', '#777'],
+			['steal', '#a71'],
+			['idle', '#3aa'],
+		],
+		'mem': [
+			['used', '#a33'],
+			['buffers', '#3aa'],
+			['cached', '#33a'],
+			['free', '#3a3'],
+		],
+		'net': [
+			['bit/s_in', '#33a', 'area'],
+			['bit/s_out', '#3a3', 'area'],
+			['err_in', '#a33', 'line'],
+			['err_out', '#aa3', 'line'],
+			['drop_in', '#a33', 'line'],
+			['drop_out', '#aa3', 'line'],
+		],
 	};
 	function graph_stat(field, subfields) {
 		var series = [];
-		Object.each(subfields, function(dates, subfield) {
-			if (subfield == 'num_cpus')
-				return;
+		colors[field].each(function(subfield_meta) {
+			var subfield = subfield_meta[0];
+			var color = subfield_meta[1];
 			var array = [];
-			Object.each(dates, function(day_array, k) {
+			Object.each(subfields[subfield], function(day_array, k) {
 				if (day_array == null)
 					return;
 				array = array.append(day_array.map(function(val, i) {
@@ -48,7 +95,8 @@ window.addEvent('domready', function() {
 			series.push({
 				'name': field + '.' + subfield,
 				'data': array,
-				'color': colors[field][subfield] || '#111',
+				'color': color,
+				'renderer': subfield_meta[2],
 			});
 		});
 		var graph_div = new Element('div');
@@ -57,7 +105,7 @@ window.addEvent('domready', function() {
 			'element': graph_div,
 			'width': 500,
 			'height': 200,
-			'renderer': 'area',
+			'renderer': field == 'net' ? 'multi' : 'area',
 			'stroke': true,
 			'series': series,
 		});
@@ -72,9 +120,9 @@ window.addEvent('domready', function() {
 			'graph': graph,
 			'timeUnit': new Rickshaw.Fixtures.Time().unit('minute'),
 		});
-		new Rickshaw.Graph.Axis.Y({
+		new Rickshaw.Graph.Axis.Y.Base1024KMGTP({
 			'graph': graph,
-			'tickFormat': Rickshaw.Fixtures.Number.formatKMBT,
+			'tickFormat': Rickshaw.Fixtures.Number.formatBase1024KMGTP,
 		});
 		graph.render();
 		$('graphs').adopt(graph_div, legend_div, new Element('br'));