RaspberryPiでリソースの可視化(NetData版)付録

提供: ディーズガレージ wiki
移動先: 案内検索

RaspberryPiでリソースの可視化(NetData版)の付録です。

貼付けテスト

参考: Custom Dashboards · firehol/netdata Wiki · GitHub

NetDataはdashboard.jsで(相対パス)ライブラリを読み込みしているのでdashboard.jsまで到達できればhtmlはどこでも設置可能です。
ただ、メジャーなライブラリを多用してるのでコンフリクトで動かなくなる状況が想像できます。
iframeの埋め込みができればいちばん簡単と思います。
stub_statusに関係するnginxのaccess.logなどはアクセス制限に引っかかれば値が取れません。
セキュリティー対策は自己責任で

ソースコード

<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
canvas {  
	width: 100px;
	height: 100px;
} 
.easyPieChartTitle {
	font-size: 11px !important;
	top: 28px !important;
}
.easyPieChartLabel {
	font-size: 16px !important;
	top: 38px !important;
}
.easyPieChartUnits {
	font-size: 11px !important;
	top: 62px !important;
}
</style>
</head>
<body>
<div data-netdata="system.cpu"
	data-chart-library="easypiechart"
	data-title="CPU"
	data-units="%"
	data-easypiechart-max-value="100"
	data-width="100"
	data-points="600"
	data-colors="#e3e000">
</div>
<div data-netdata="sensors.temp_thermal_zone0_thermal_thermal_zone0"
	data-chart-library="easypiechart"
	data-title="TEMP"
	data-units="°C"
	data-easypiechart-max-value="85"
	data-width="100"
	data-points="600"
	data-colors="#ff8400">
</div>
<div data-netdata="system.ram"
	data-dimensions="free"
	data-chart-library="easypiechart"
	data-title="Free RAM"
	data-units="MB"
	data-easypiechart-max-value="1024"
	data-width="100"
	data-points="600"
	data-colors="#ff00de">
</div>
<div data-netdata="system.ipv4"
	data-dimensions="received"
	data-chart-library="easypiechart"
	data-title="IPv4 IN"
	data-units="Kbps"
	data-width="100"
	data-points="600">
</div>
<div data-netdata="system.ipv4"
	data-dimensions="sent"
	data-chart-library="easypiechart"
	data-title="IPv4 OUT"
	data-units="Kbps"
	data-width="100"
	data-points="600">
</div>
<script type="text/javascript" src="http://dz.plala.jp:8081/dashboard.js"></script>
<script>
NETDATA.options.current.stop_updates_when_focus_is_lost = false;
</script>
</body>
</html>

参考雛型

http://dz.plala.jp:8081/index.html
http://dz.plala.jp:8081/tv.html
http://dz.plala.jp:8081/dashboard.html
http://dz.plala.jp:8081/infographic.html
http://dz.plala.jp:8081/demo.html
http://dz.plala.jp:8081/demo2.html
http://dz.plala.jp:8081/demosites.html
http://dz.plala.jp:8081/demosites2.html
http://dz.plala.jp:8081/goto-host-from-alarm.html
http://dz.plala.jp:8081/registry.html

オリジナル作成下調べ

NetDataのビジュアル部分は結局URL叩き返ってくる配列を処理するだけなのでdashboard.jsに頼らずとも作成できます。
APIドキュメントが見つからないので大雑把なまとめ

http://dz.plala.jp:8081/api/v1/badge.svg?chart=CHARTS_ID
http://dz.plala.jp:8081/api/v1/data?chart=CHARTS_ID
http://dz.plala.jp:8081/api/v1/chart?chart=CHARTS_ID
http://dz.plala.jp:8081/api/v1/charts
http://dz.plala.jp:8081/api/v1/registry?action=hello access delete search
http://dz.plala.jp:8081/api/v1/alarms
http://dz.plala.jp:8081/api/v1/allmetrics?format=shell prometheus prometheus_all_hosts json

場合により使えるクエリパラメータ
&format=array|json|csv|csvjsonarray|tsv|html|datatable|datasource
&options=absolute|ms|flip|jsonwrap|nonzero|percentage|objectrows
&options=seconds|milliseconds
&before=数値 &after=-数値 &points=数値 &group=average &dimensions=dimensions名 &_=UNIX時間

http://dz.plala.jp:8081/api/v1/charts
http://dz.plala.jp:8081/api/v1/chart?chart=system.cpu
http://dz.plala.jp:8081/api/v1/data?chart=system.cpu&after=-1&format=array

EasyPieChart

参考: EASY PIE CHART by rendro
参考: GitHub - rendro/easy-pie-chart

EasyPieChartは100%が基準の作りのため100やパーセント以外の数値や単位では動かせません。
ライブラリを改変して任意の値に対応させます。

使用ライブラリ

https://github.com/rendro/easy-pie-chart/blob/master/dist/jquery.easypiechart.js

改変箇所
190行目 書き換え

// draw bar
//drawCircle(color, options.lineWidth, percent / 100);
drawCircle(color, options.lineWidth, percent / options.maxValue);

219行目 追記

var defaultOptions = {
    maxValue: 100,
    barColor: '#ef1e25',

ソースコード

<!DOCTYPE html>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
* {
	margin: 0;
	padding: 0;
}
html, body {
	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
	font-style: normal;
	font-weight: normal;
}
.gauge-container {
	position: relative;
	height: 100px;
	width: 100px;
	float: left;
}
canvas {
	position: absolute;
	top: 0;
	left: 0;
}
.gauge {
	width: 100px;
	height: 100px;
	display: table-cell;
	vertical-align: middle;
	text-align: center;
}
.title, .label, .units {
	width: 100%;
	color: #999;
}
.title, .units {
	font-size: 11px;
}
.label {
	display: inline-block;
	text-align: center;
	font-size: 16px;
	font-weight: bold;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<script src="jquery.easypiechart.js"></script>
<script>
$(function() {
	var gaugeList = [
		{
			title: 'CPU',
			units: '%',
			max: 100,
			color: '#e3e000'
		},{
			title: 'TEMP',
			units: '°C',
			max: 85,
			color: '#ff8400'
		},{
			title: 'Free RAM',
			units: 'MB',
			max: 1024,
			color: '#ff00de'
		},{
			title: 'IPv4 IN',
			units: 'Kbps',
			max: 100000,
			color: '#3366cc'
		},{
			title: 'IPv4 OUT',
			units: 'Kbps',
			max: 100000,
			color: '#dc3912'
		}
	];
	
	for (var i = 0; i < gaugeList.length; i++) {
		$('body').append('<div class="gauge-container"><div id="gauge' + i + '" class="gauge"><span class="title">' + gaugeList[i].title + '</span><span class="label"></span><span class="units">' + gaugeList[i].units + '</span></div></div>');
		$('#gauge' + i).easyPieChart({
			size: 100,
			maxValue: gaugeList[i].max,
			barColor: gaugeList[i].color,
			trackColor: '#eee',
			scaleColor: 'rgba(0,0,0,0)',
			lineWidth: 4,
			//easing: 'easeOutQuart',
			onStep: function(from, to, currentValue) {
				$(this.el).find('.label').text(currentValue.toFixed(2));
			}
		});
	}
	
	setInterval(function() {
		$.ajax({
			url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
			type: 'GET',
			cache: false,
			dataType: 'json',
			timeout: 4000
		}).done(function (obj) {
			$('#gauge0').data('easyPieChart').update(100 - obj["system.cpu"]["dimensions"]["idle"]["value"]);
			$('#gauge1').data('easyPieChart').update(obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"]);
			$('#gauge2').data('easyPieChart').update(obj["system.ram"]["dimensions"]["free"]["value"]);
			$('#gauge3').data('easyPieChart').update(obj["system.ipv4"]["dimensions"]["InOctets"]["value"]);
			$('#gauge4').data('easyPieChart').update(Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]));
		});
	}, 1000);
});
</script>
</head>
<body>
</body>
</html>

justGage

参考: justGage.com
参考: GitHub - toorshia/justgage

ソースコード (IEとEdgeのローカルファイルパス起動で不具合あり)

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
* {
	margin: 0;
	padding: 0;
}
html, body {
	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
	font-style: normal;
	font-weight: normal;
}
.gauge {
	position: relative;
	width: 120px;
	height: 100px;
	float: left;
}
svg {
	position: absolute !important;
	margin-top: 10px;
}
.title, .units {
	position: absolute;
	width: 100%;
	text-align: center;
	font-size: 11px;
	color: #999;
}
.title {
	margin-top: 9px;
}
.units {
	margin-top: 82px;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.2.7/raphael.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js"></script>
<script>
$(function() {
	var gaugeList = [
		{
			title: 'CPU',
			units: '%',
			min: 0,
			max: 100,
			color: '"#eaed73", "#f0f700", "#abb100"'
		},{
			title: 'TEMP',
			units: '°C',
			min: 0,
			max: 85,
			color: '"#ffc17e", "#ff890c", "#bf6300"'
		},{
			title: 'Free RAM',
			units: 'MB',
			min: 0,
			max: 1024,
			color: '"#ff7ef8", "#ff0cf1", "#bf00b2"'
		},{
			title: 'IPv4 IN',
			units: 'Kbps',
			min: 0,
			max: 100000,
			color: '"#a19dff", "#2b22ff", "#0800cf"'
		},{
			title: 'IPv4 OUT',
			units: 'Kbps',
			min: 0,
			max: 100000,
			color: '"#ff7e7d", "#ff0c0c", "#bf0000"'
		}
	];
	
	if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
		var dflt = {
			value: 0,
			decimals: 2,
			counter: true,
			gaugeWidthScale: 1.0,
			hideMinMax: true,
			valueMinFontSize: 14,
			valueFontFamily: "Arial",
			valueFontColor: "#999",
			refreshAnimationTime: 1000
		};
	} else {
		var dflt = {
			value: 0,
			decimals: 2,
			counter: true,
			gaugeWidthScale: 1.0,
			hideMinMax: true,
			valueMinFontSize: 14,
			valueFontFamily: "Arial",
			valueFontColor: "#999",
			refreshAnimationTime: 1000,
			startAnimationType: "linear",
			refreshAnimationType: "linear",
			showInnerShadow: true,
			shadowOpacity: 0.3,
			shadowSize: 1,
			shadowVerticalOffset: 1
		};
	};
	
	for (var i = 0; i < gaugeList.length; i++) {
		$('body').append('<div id="gauge' + i + '" class="gauge"><span class="title">' + gaugeList[i].title + '</span><span class="units">' + gaugeList[i].units + '</span></div>');
		eval('var gauge' + i + ' = new JustGage({id: "gauge' + i + '", min: ' + gaugeList[i].min + ', max: ' + gaugeList[i].max + ', levelColors: [' + gaugeList[i].color + '], defaults: dflt})');
	};
	
	setInterval(function() {
		$.ajax({
			url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
			type: 'GET',
			cache: false,
			dataType: 'json',
			timeout: 4000
		}).done(function (obj) {
			gauge0.refresh(100 - obj["system.cpu"]["dimensions"]["idle"]["value"]);
			gauge1.refresh(obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"]);
			gauge2.refresh(obj["system.ram"]["dimensions"]["free"]["value"]);
			gauge3.refresh(obj["system.ipv4"]["dimensions"]["InOctets"]["value"]);
			gauge4.refresh(Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]));
		});
	}, 1000);
});
</script>
</head>
<body>
</body>
</html>

カラーチャート
Color chart.jpg

gauge.js Donut

参考: gauge.js
参考: GitHub - bernii/gauge.js

ソースコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
* {
	margin: 0;
	padding: 0;
}
html, body {
	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
	font-style: normal;
	font-weight: normal;
}
.gauge {
	position: relative;
	width: 120px;
	height: 120px;
	float: left;
}
canvas {
	position: absolute;
	width: 180px;
	height: 90px;
	margin-left: -30px;
	margin-top: 14px;
}
.value {
	position: absolute;
	width: 100%;
	text-align: center;
	font-size: 14px;
	color: #999;
}
.title, .value, .units {
	position: absolute;
}
.title {
	width: 100%;
	text-align: center;
	margin-top: 36px;
	font-size: 11px;
	color: #999;
}
.value {
	width: 100%;
	text-align: center;
	margin-top: 52px;
	font-size: 16px;
	font-weight: bold;
	color: #999;
}
.units {
	width: 100%;
	text-align: center;
	margin-top: 74px;
	font-size: 11px;
	color: #999;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="gauge.min.js"></script>
<script>
$(function() {
	// Polyfill for IE11
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
	if (typeof Object.assign != 'function') {
		Object.assign = function(target, varArgs) { // .length of function is 2
			'use strict';
			if (target == null) { // TypeError if undefined or null
				throw new TypeError('Cannot convert undefined or null to object');
			}
			
			var to = Object(target);
			
			for (var index = 1; index < arguments.length; index++) {
				var nextSource = arguments[index];
				
				if (nextSource != null) { // Skip over if undefined or null
					for (var nextKey in nextSource) {
						// Avoid bugs when hasOwnProperty is shadowed
						if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
							to[nextKey] = nextSource[nextKey];
						}
					}
				}
			}
			return to;
		};
	}
	
	var gaugeList = [{
		title: 'CPU',
		units: '%',
		min: 0,
		max: 100,
		color: '#eaed73'
	}, {
		title: 'TEMP',
		units: '°C',
		min: 0,
		max: 85,
		color: '#ffc17e'
	}, {
		title: 'Free RAM',
		units: 'MB',
		min: 0,
		max: 1024,
		color: '#ff7ef8'
	}, {
		title: 'IPv4 IN',
		units: 'Kbps',
		min: 0,
		max: 100000,
		color: '#a19dff'
	}, {
		title: 'IPv4 OUT',
		units: 'Kbps',
		min: 0,
		max: 100000,
		color: '#ff7e7d'
	}];
	
	var dflt = {
		angle: 0.35,
		lineWidth: 0.08,
		radiusScale: 1.0,
		pointer: {
			length: 1,
			strokeWidth: 0.05,
			color: '#e6e9ec'
		},
		limitMax: false,
		limitMin: false,
		strokeColor: '#edebeb',
		colorStart: '#fff',
		generateGradient: true,
		highDpiSupport: true
	};
	
	var animSpped = 200;
	
	for (var i = 0; i < gaugeList.length; i++) {
		$('body').append('<div class="gauge"><canvas id="gauge' + i + '"></canvas><span class="value" id="value' + i + '"></span><span class="title">' + gaugeList[i].title + '</span><span class="units">' + gaugeList[i].units + '</span>');
		eval('var gauge' + i + 'conf = Object.assign({}, {colorStop: "' + gaugeList[i].color + '"}, dflt);');
		eval('var gauge' + i + ' = new Donut(document.getElementById("gauge' + i + '")).setOptions(gauge' + i + 'conf);');
		eval('var textRenderer = new TextRenderer(document.getElementById("value' + i + '"));');
		eval('textRenderer.render = function(gauge' + i + ') {this.el.innerHTML = gauge' + i + '.displayedValue.toFixed(2);};');
		eval('gauge' + i + '.maxValue = ' + gaugeList[i].max + '; gauge' + i + '.setMinValue(' + gaugeList[i].min + '); gauge' + i + '.animationSpeed = ' + animSpped + '; gauge' + i + '.set(' + gaugeList[i].min + '); gauge' + i + '.setTextField(textRenderer);');
	};
	
	setInterval(function() {
		$.ajax({
			url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
			type: 'GET',
			cache: false,
			dataType: 'json',
			timeout: 4000
		}).done(function(obj) {
			gauge0.set(100 - obj["system.cpu"]["dimensions"]["idle"]["value"]);
			gauge1.set(obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"]);
			gauge2.set(obj["system.ram"]["dimensions"]["free"]["value"]);
			gauge3.set(obj["system.ipv4"]["dimensions"]["InOctets"]["value"]);
			gauge4.set(Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]));
		});
	}, 1000);
});
</script>
</head>
<body>
</body>
</html>

gauge.js Gauge

参考: gauge.js
参考: GitHub - bernii/gauge.js

ソースコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
* {
	margin: 0;
	padding: 0;
}
html, body {
	font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
	font-style: normal;
	font-weight: normal;
}
.gauge {
	position: relative;
	width: 125px;
	height: 90px;
	float: left;
}
canvas {
	position: absolute;
	width: 125px;
	height: 90px;
}
.value {
	position: absolute;
	width: 100%;
	text-align: center;
	font-size: 14px;
	color: #999;
}
.title, .value, .units {
	position: absolute;
}
.title {
	width: 100%;
	text-align: center;
	margin-top: 3px;
	font-size: 11px;
	color: #999;
}
.value {
	width: 100%;
	text-align: center;
	margin-top: 30px;
	font-size: 15px;
	font-weight: bold;
	color: #fff;
	text-shadow:0px 1px 2px #666;
}
.units {
	left: 7px;
	bottom: 6px;
	font-size: 11px;
	color: #999;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="gauge.min.js"></script>
<script>
$(function() {
	// Polyfill for IE11
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
	if (typeof Object.assign != 'function') {
		Object.assign = function(target, varArgs) { // .length of function is 2
			'use strict';
			if (target == null) { // TypeError if undefined or null
				throw new TypeError('Cannot convert undefined or null to object');
			}
			
			var to = Object(target);
			
			for (var index = 1; index < arguments.length; index++) {
				var nextSource = arguments[index];
				
				if (nextSource != null) { // Skip over if undefined or null
					for (var nextKey in nextSource) {
						// Avoid bugs when hasOwnProperty is shadowed
						if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
							to[nextKey] = nextSource[nextKey];
						}
					}
				}
			}
			return to;
		};
	}
	
	var gaugeList = [
		{
			title: 'CPU',
			units: '%',
			min: 0,
			max: 100,
			color: '[0.0, "#eaed73"],[0.50, "#f0f700"],[1.0, "#abb100"]'
		},{
			title: 'TEMP',
			units: '°C',
			min: 0,
			max: 85,
			color: '[0.0, "#ffc17e"],[0.50, "#ff890c"],[1.0, "#bf6300"]'
		},{
			title: 'Free RAM',
			units: 'MB',
			min: 0,
			max: 1024,
			color: '[0.0, "#ff7ef8"],[0.50, "#ff0cf1"],[1.0, "#bf00b2"]'
		},{
			title: 'IPv4 IN',
			units: 'Kbps',
			min: 0,
			max: 100000,
			color: '[0.0, "#a19dff"],[0.50, "#2b22ff"],[1.0, "#0800cf"]'
		},{
			title: 'IPv4 OUT',
			units: 'Kbps',
			min: 0,
			max: 100000,
			color: '[0.0, "#ff7e7d"],[0.50, "#ff0c0c"],[1.0, "#bf0000"]'
		}
	];
	
	var dflt = {
		angle: 0.12,
		lineWidth: 0.45,
		radiusScale: 0.8,
		pointer: {
			length: 0.7,
			strokeWidth: 0.04,
			color: '#c0c0c0'
		},
		limitMax: false,
		limitMin: false,
		strokeColor: '#edebeb',
		generateGradient: true,
		highDpiSupport: true
	};
	
	var animSpped = 200;
	
	for (var i = 0; i < gaugeList.length; i++) {
		$('body').append('<div class="gauge"><canvas id="gauge' + i + '"></canvas><span class="value" id="value' + i + '"></span><span class="title">' + gaugeList[i].title + '</span><span class="units">' + gaugeList[i].units + '</span>');
		eval('var gauge' + i + 'conf = Object.assign({}, {percentColors: [' + gaugeList[i].color + ']}, dflt);');
		eval('var gauge' + i + ' = new Gauge(document.getElementById("gauge' + i + '")).setOptions(gauge' + i + 'conf);');
		eval('var textRenderer = new TextRenderer(document.getElementById("value' + i + '"));');
		eval('textRenderer.render = function(gauge' + i + ') {this.el.innerHTML = gauge' + i + '.displayedValue.toFixed(2);};');
		eval('gauge' + i + '.maxValue = ' + gaugeList[i].max + '; gauge' + i + '.setMinValue(' + gaugeList[i].min + '); gauge' + i + '.animationSpeed = ' + animSpped + '; gauge' + i + '.set(' + gaugeList[i].min + '); gauge' + i + '.setTextField(textRenderer);');
	};
	
	setInterval(function() {
		$.ajax({
			url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
			type: 'GET',
			cache: false,
			dataType: 'json',
			timeout: 4000
		}).done(function (obj) {
			gauge0.set(100 - obj["system.cpu"]["dimensions"]["idle"]["value"]);
			gauge1.set(obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"]);
			gauge2.set(obj["system.ram"]["dimensions"]["free"]["value"]);
			gauge3.set(obj["system.ipv4"]["dimensions"]["InOctets"]["value"]);
			gauge4.set(Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]));
		});
	}, 1000);
});
</script>
</head>
<body>
</body>
</html>

Canvas Gauges

参考: Canvas Gauges
参考: GitHub - Mikhus/canvas-gauges

ソースコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
* {
	margin: 0;
	padding: 0;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="gauge.min_214.js"></script>
<script>
$(function() {
	// Polyfill for IE11
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
	if (!String.prototype.repeat) {
		String.prototype.repeat = function(count) {
			'use strict';
			if (this == null) {
				throw new TypeError('can\'t convert ' + this + ' to object');
			}
			var str = '' + this;
			count = +count;
			if (count != count) {
				count = 0;
			}
			if (count < 0) {
				throw new RangeError('repeat count must be non-negative');
			}
			if (count == Infinity) {
				throw new RangeError('repeat count must be less than infinity');
			}
			count = Math.floor(count);
			if (str.length == 0 || count == 0) {
				return '';
			}
			// Ensuring count is a 31-bit integer allows us to heavily optimize the
			// main part. But anyway, most current (August 2014) browsers can't handle
			// strings 1 << 28 chars or longer, so:
			if (str.length * count >= 1 << 28) {
				throw new RangeError('repeat count must not overflow maximum string size');
			}
			var rpt = '';
			for (;;) {
				if ((count & 1) == 1) {
					rpt += str;
				}
				count >>>= 1;
				if (count == 0) {
					break;
				}
				str += str;
			}
			// Could we try:
			// return Array(count + 1).join(this);
			return rpt;
		}
	}
	
	// Polyfill for IE11
	// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
	if (typeof Object.assign != 'function') {
		Object.assign = function(target, varArgs) { // .length of function is 2
			'use strict';
			if (target == null) { // TypeError if undefined or null
				throw new TypeError('Cannot convert undefined or null to object');
			}
			
			var to = Object(target);
			
			for (var index = 1; index < arguments.length; index++) {
				var nextSource = arguments[index];
				
				if (nextSource != null) { // Skip over if undefined or null
					for (var nextKey in nextSource) {
						// Avoid bugs when hasOwnProperty is shadowed
						if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
							to[nextKey] = nextSource[nextKey];
						}
					}
				}
			}
			return to;
		};
	}
	
	var gaugeList = [{
		title: 'CPU',
		units: '%',
		minValue: 0,
		maxValue: 100,
		majorTicks: '"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"',
		minorTicks: 2,
		highlightsLow: 'from: 60, to: 80, color: "rgba(243, 239, 118, 1)"',
		highlightsHigh: 'from: 80, to: 100, color: "rgba(242, 166, 138, 1)"'
	}, {
		title: 'TEMP',
		units: '°C',
		minValue: 0,
		maxValue: 80,
		majorTicks: '"0", "10", "20", "30", "40", "50", "60", "70", "80"',
		minorTicks: 2,
		highlightsLow: 'from: 60, to: 70, color: "rgba(243, 239, 118, 1)"',
		highlightsHigh: 'from: 70, to: 80, color: "rgba(242, 166, 138, 1)"'
	}, {
		title: 'Free RAM',
		units: 'MB',
		minValue: 0,
		maxValue: 1024,
		majorTicks: '"0", "512", "1024"',
		minorTicks: 2,
		highlightsLow: 'from: 256, to: 512, color: "rgba(243, 239, 118, 1)"',
		highlightsHigh: 'from: 0, to: 256, color: "rgba(242, 166, 138, 1)"'
	}, {
		title: 'IPv4 IN',
		units: 'Mbps',
		minValue: 0,
		maxValue: 100,
		majorTicks: '"0", "20", "40", "60", "80", "100"',
		minorTicks: 2,
		highlightsLow: 'from: 60, to: 80, color: "rgba(243, 239, 118, 1)"',
		highlightsHigh: 'from: 80, to: 100, color: "rgba(242, 166, 138, 1)"'
	}, {
		title: 'IPv4 OUT',
		units: 'Mbps',
		minValue: 0,
		maxValue: 100,
		majorTicks: '"0", "20", "40", "60", "80", "100"',
		minorTicks: 2,
		highlightsLow: 'from: 60, to: 80, color: "rgba(243, 239, 118, 1)"',
		highlightsHigh: 'from: 80, to: 100, color: "rgba(242, 166, 138, 1)"'
	}];
	
	var defaultSetting = {
		width: 120,
		height: 120,
		value: 0,
		valueInt: 0,
		valueDec: 2,
		colorNeedle: 'rgba(227, 33, 33, 1)',
		colorNeedleEnd: 'rgba(255, 119, 119, 1)',
		colorNeedleCircleOuter: '#fff',
		colorNeedleCircleOuterEnd: '#ccc',
		colorNeedleCircleInner: '#ccc',
		colorNeedleCircleInnerEnd: '#fff',
		colorNeedleShadowUp: 'rgba(0, 0, 0, 0)',
		colorNeedleShadowDown: 'rgba(0, 0, 0, 0.3)',
		colorValueBoxRect: '#fff',
		colorValueBoxRectEnd: '#eee',
		colorValueBoxBackground: '#ddd',
		colorValueBoxShadow: 'rgba(0, 0, 0, 0.5)',
		colorValueText: '#444',
		colorValueTextShadow: 'rgba(0, 0, 0, 0.3)',
		colorBorderShadow: 'rgba(0, 0, 0, 0.5)',
		colorBorderOuter: '#ccc',
		colorBorderOuterEnd: '#ccc',
		colorBorderMiddle: '#ccc',
		colorBorderMiddleEnd: '#ccc',
		borderOuterWidth: 0,
		borderMiddleWidth: 0,
		borderInnerWidth: 0,
		colorPlate: '#fafafa',
		colorMajorTicks: '#444',
		colorMinorTicks: '#444',
		colorTitle: '#444',
		colorUnits: '#444',
		colorNumbers: '#444',
		fontNumbersSize: '28',
		fontTitleWeight: 'bold',
		fontTitleSize: '30',
		fontUnitsSize: '30',
		fontValueSize: '30',
		fontValueWeight: 'lighter',
		highlightsWidth: 12,
		numbersMargin: -6
	};
	var customAnimation = {
		animationRule: 'elastic',
		animationDuration: 1000,
		animatedValue: true
	};
	
	for (var i = 0; i < gaugeList.length; i++) {
		eval('var gauge' + i + 'Conf = Object.assign({}, {renderTo: "gauge' + i + '", title: "' + gaugeList[i].title + '",	units: "' + gaugeList[i].units + '", minValue: ' + gaugeList[i].minValue + ', maxValue: ' + gaugeList[i].maxValue + ', majorTicks: [' + gaugeList[i].majorTicks + '], minorTicks: ' + gaugeList[i].minorTicks + ', highlights: [{' + gaugeList[i].highlightsLow + '},{' + gaugeList[i].highlightsHigh + '}]}, customAnimation, defaultSetting);');
		$('body').append('<canvas id="gauge' + i + '"></canvas>');
		eval('var gauge' + i + ' = new RadialGauge(gauge' + i + 'Conf)');
		eval('gauge' + i + '.draw()');
	};
	
	setInterval(function() {
		$.ajax({
			url: 'http://dz.plala.jp:8081/api/v1/allmetrics?format=json',
			type: 'GET',
			cache: false,
			dataType: 'json',
			timeout: 4000
		}).done(function(obj) {
			gauge0.value = (100 - obj["system.cpu"]["dimensions"]["idle"]["value"]);
			gauge1.value = (obj["sensors.temp_thermal_zone0_thermal_thermal_zone0"]["dimensions"]["sys_devices_virtual_thermal_thermal_zone0_temp"]["value"]);
			gauge2.value = (obj["system.ram"]["dimensions"]["free"]["value"]);
			gauge3.value = (obj["system.ipv4"]["dimensions"]["InOctets"]["value"] / 1000);
			gauge4.value = (Math.abs(obj["system.ipv4"]["dimensions"]["OutOctets"]["value"]) / 1000);
		});
	}, 1000);
});
</script> 
</head>
<body>
</body>
</html>

Google Charts

参考: Google Charts - Visualization: Gauge

ソースコード

<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<style>
.gauge {
	float: left;
}
.gauge svg g text {
	font-size: 8px;
}
.gauge svg g g text {
	font-size: 11px;
}
</style>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
	var ip = 'http://dz.plala.jp:8081/';
	
	var gaugeList = [
		{
			title: 'CPU',
			url: 'api/v1/data?chart=system.cpu&after=-1&format=array',
			units: '%',
			max: 100,
			majorTicks: '"0", "10", "20", "30", "40", "50", "60", "70", "80", "90", "100"',
			minorTicks: 2,
			yellowFrom: 60,
			yellowTo: 80,
			redFrom: 80,
			redTo: 100
		},{
			title: 'TEMP',
			url: 'api/v1/data?chart=sensors.temp_thermal_zone0_thermal_thermal_zone0&after=-1&format=array',
			units: '°C',
			max: 80,
			majorTicks: '"0", "10", "20", "30", "40", "50", "60", "70", "80"',
			minorTicks: 2,
			yellowFrom: 60,
			yellowTo: 70,
			redFrom: 70,
			redTo: 80
		},{
			title: 'Free RAM',
			url: 'api/v1/data?chart=system.ram&after=-1&format=array&dimensions=free',
			units: 'MB',
			max: 1024,
			majorTicks: '"0", "512", "1024"',
			minorTicks: 2,
			yellowFrom: 256,
			yellowTo: 512,
			redFrom: 0,
			redTo: 256
		},{
			title: 'IPv4 IN',
			url: 'api/v1/data?chart=system.ipv4&after=-1&format=array&dimensions=received',
			units: 'Kbps',
			max: 100000,
			majorTicks: '"0", "50000", "100000"',
			minorTicks: 2,
			yellowFrom: 50000,
			yellowTo: 75000,
			redFrom: 75000,
			redTo: 100000
		},{
			title: 'IPv4 OUT',
			url: 'api/v1/data?chart=system.ipv4&after=-1&format=array&dimensions=sent',
			units: 'Kbps',
			max: 100000,
			majorTicks: '"0", "50000", "100000"',
			minorTicks: 2,
			yellowFrom: 50000,
			yellowTo: 75000,
			redFrom: 75000,
			redTo: 100000
		}
	];
	
	var gaugeWidth = 120;
	var gaugeHeight = 120;
	
	google.charts.load('current', {'packages': ['gauge']});
	
	for (var i = 0; i < gaugeList.length; i++) {
		$('body').append('<div id="chart' + i + '" class="gauge" style="width: ' + gaugeWidth + '; height: ' + gaugeHeight + ';"></div>');
		eval('function drawChart' + i + '() {var data = google.visualization.arrayToDataTable([["Label", "Value"],["' + gaugeList[i].title + '", 0]]); var options = {animation: {duration: 1000, easing: "linear",}, width: ' + gaugeWidth + ',	height: ' + gaugeHeight + ', max: ' + gaugeList[i].max + ', majorTicks : [' + gaugeList[i].majorTicks + '] ,minorTicks: ' + gaugeList[i].minorTicks + ', yellowFrom: ' + gaugeList[i].yellowFrom + ', yellowTo: ' + gaugeList[i].yellowTo + ', redFrom: ' + gaugeList[i].redFrom + ', redTo: ' + gaugeList[i].redTo + '}; var chart = new google.visualization.Gauge(document.getElementById("chart' + i + '")); chart.draw(data, options); setInterval(function() {$.ajax({url: "' + ip + gaugeList[i].url + '", type: "GET", cache: false, dataType: "json", success: function(json) {data.setValue(0, 1, Math.abs(json[0]).toFixed(2)); var formatter = new google.visualization.NumberFormat({suffix: "' + gaugeList[i].units + '",pattern:"#"}); formatter.format(data,1); chart.draw(data, options);}});}, 1000);}');
		eval('google.charts.setOnLoadCallback(drawChart' + i + ');');
	};
});
</script>
</head>
<body>
</body>
</html>