|
~ To be, or not to be, or to forget all. ~ null-i.net |
| Linux/sarをグラフ化その3(tableタグでグラフを描く | |
|
グラフをHTMLのtableタグで描く例(2017-03-14)
以下、HTMLとJavaScriptのみでグラフ描画します。 PCでご覧になった方は、比較的すんなり表示できたと思います。 Shellの使い方†この shellは cgi を想定していますが、shell単体でも問題なく機能します。 それ以外で、更新しなければならない箇所は2つ、
最初は、SARFILE行だけ書き換えて、感覚をつかんでください。 以下、sar から グラフ付きHTMLファイルを描くShellです。 グラフを作るshell†#!/bin/sh
export LANG=C
#----------------------------------------------------------
# 値を変更する箇所は 2箇所
# (参照:cpu_all_title, cpu_all_x, cpu_all_y)
# - sar と awk の値を保持するところ、
# - それらの値を使う document.addEventListener
#
# CGIにせずにファイル取得のみであれば、リダイレクトすればOK.
# printf '%s' "$body" >> sample.html
#----------------------------------------------------------
# sar.log の場所を指定
SARFILE=`ls -t1 /var/log/sa/sa* | tail -1`
SARINFO=`basename $SARFILE`
cpu_all_title="cpu [useage %]"
cpu_all_x=`sar -f $SARFILE -u |\
egrep -vi '^$|average|CPU' |\
grep " all " |\
awk '{ printf("\"%s\",", $1); }' |\
sed -e 's/,$//'`
cpu_all_y=`sar -f $SARFILE -u |\
egrep -vi '^$|average|CPU' |\
grep " all " |\
awk '{ printf("%.2f,", 100 - $8); }' |\
sed -e 's/,$//'`
mem_use_title="memory [memused %]"
mem_use_x=`sar -f $SARFILE -r |\
egrep -vi '^$|average|memused|Linux' |\
awk '{ printf("\"%s\",", $1); }' |\
sed -e 's/,$//'`
mem_use_y=`sar -f $SARFILE -r |\
egrep -vi '^$|average|memused|Linux' |\
awk '{ printf("%.2f,", $4); }' |\
sed -e 's/,$//'`
load_1m_title="load average 1min [ldavg-1]"
load_1m_x=`sar -f $SARFILE -q |\
egrep -vi '^$|average|ldavg|Linux' |\
awk '{ printf("\"%s\",", $1); }' |\
sed -e 's/,$//'`
load_1m_y=`sar -f $SARFILE -q |\
egrep -vi '^$|average|ldavg' |\
awk '{ printf("%.2f,", $4); }' |\
sed -e 's/,$//'`
rxp_eth0_title="dev eth0 [rxpck/s]"
rxk_eth0_title="dev eth0 [rxkB/s]"
rxp_eth0_x=`sar -f $SARFILE -n DEV |\
egrep -vi '^$|average|IFACE' |\
grep eth0 |\
awk '{ printf("\"%s\",", $1); }' |\
sed -e 's/,$//'`
rxp_eth0_y=`sar -f $SARFILE -n DEV |\
egrep -vi '^$|average|IFACE' |\
grep eth0 |\
awk '{ printf("%.2f,", $3); }' |\
sed -e 's/,$//'`
rxk_eth0_y=`sar -f $SARFILE -n DEV |\
egrep -vi '^$|average|IFACE' |\
grep eth0 |\
awk '{ printf("%.2f,", $5); }' |\
sed -e 's/,$//'`
#---(sarの変数への格納 ここまで)-------------------------------------------------------
body=`cat <<EOS
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />
<meta http-equiv="content-style-type" content="text/css" />
<meta name="viewport" content="width=device-width,initial-scale=1">
<title> sar graph </title>
<style type="text/css">
<!--
body {
background-color:black;
color: #eeeeee;
margin-left:2%;
margin-right:2%;
font-size:100%;
}
table {
// clear gaps, and fix size, even if the screen of the Web browser is scaled.
padding:0px; border: none; margin:0px;
border-collapse: collapse;
height:auto;
background-color:white;
}
td {
// dot graphic
// if graph input is not enough, set large value width and height px.
padding:0px;
width: 1px;
height: 1px;
}
td.left {
// if change width, see makeTable() and update <table width>
padding:0px; margin:0px;
font-size: 2px;
background-color: gray;
width: 55px;
}
td.bottom {
padding:0px; margin:0px;
font-size: 2px;
background-color: gray;
}
td.end {
padding:0px; margin:0px;
background-color:black;
}
div#HintDiv {
visibility: hidden;
position: fixed;
font-size: 100%;
padding: 1em;
color: black;
background-color: white;
opacity: 0.8;
}
h2, h3 {
border-bottom: 3px solid #448888;
border-top: 1px solid #448888;
border-left: 4px solid #224444;
border-right: 8px solid #224444;
color: #aacccc;
width: 80%;
background-color:#88aaaa;
margin:0px 0px 2px 0px;
}
-->
</style>
<script type="text/javascript">
<!--
var HintTimer=null;
var HintMesg = "";
function addHintListener(index){
var hint_obj = document.getElementById(index);
if(hint_obj == null || hint_obj == undefined){
return;
}
hint_obj.addEventListener("mouseover", function(e) {
if(HintTimer != null){ return; }
var obj = document.getElementById("HintDiv");
obj.innerHTML = hint_obj.class;
obj.style.top = e.clientY + "px";
obj.style.left = e.clientX + "px";
obj.style.visibility = "visible";
}, false);
hint_obj.addEventListener("mouseout", function(e) {
if(HintTimer != null){ return; }
var obj = document.getElementById("HintDiv");
obj.innerHTML = "";
obj.style.visibility = "hidden";
}, false);
hint_obj.addEventListener("touchend", function(e) {
var obj = document.getElementById("HintDiv");
if(HintMesg == "" || HintMesg != hint_obj.class){
obj.style.top = e.changedTouches[0].pageY + "px";
obj.style.left = e.changedTouches[0].pageX + "px";
obj.style.position = "absolute";
obj.innerHTML = HintMesg = hint_obj.class;
obj.style.visibility = "visible";
clearInterval(HintTimer);
HintTimer = setInterval(function(e) {
if(HintMesg != ""){
obj.innerHTML = HintMesg = "";
obj.style.visibility = "hidden";
}
if(HintTimer != null){
clearInterval(HintTimer);
HintTimer = null;
}
}, 7000);
}
else {
obj.innerHTML = HintMesg = "";
obj.style.visibility = "hidden";
if(HintTimer != null){
clearInterval(HintTimer);
HintTimer = null;
}
}
}, false);
}
function makeTable(header, index, x_range, y_range, x_min, x_max, y_min, y_max){
var string = "<h3>" + header + "</h3>";
string += "<table id=\"" + index + "\" width=" + (x_range + 55) + "px >";
var pre = Math.floor(y_range / 2);
for(var y=0; y < y_range; y++){
string += "<tr>";
if(y == 0){
string += "<td rowspan=" + pre
+ " class=left valign=top align=right>" + y_max + "</td>";
}
else if(y == pre){
string += "<td rowspan=" + (y_range - pre)
+ " class=left valign=bottom align=right>" + y_min + "</td>";
}
for(var x=0; x < x_range; x++){
string += "<td id=\"" + index + "_" + x + "_" + y + "\" ";
if(y==pre){
string += "style=background-color:#dddddd;";
}
string += " />"
}
string += "</tr>";
}
pre = Math.floor(x_range / 2);
string += "<tr><td class=bottom />";
string += "<td colspan=" + pre
+ " class=bottom valign=bottom align=left>" + x_min + "</td>";
string += "<td colspan=" + (x_range - pre + 1)
+ " class=bottom valign=bottom align=right>" + x_max + "</td>";
string += "</tr></table>";
document.body.innerHTML += string;
}
function setTable(index, x_plot, y_plot, comment){
var td_id = document.getElementById(index + "_" + x_plot + "_" + y_plot);
if(td_id == null || td_id == undefined){
return;
}
td_id.style.backgroundColor = "#99dd99";
td_id.class = comment;
addHintListener(index + "_" + x_plot + "_" + y_plot);
}
function initGraph(header, index, x_array, y_array, type){
var y_pixel=100;
var y_top=100;
var y_bottom=0;
if(type == null || type != "percent"){
for(var i=0; i<y_array.length; i++){
if(i==0){ y_bottom=y_array[i]; y_top=y_array[i]; }
if(y_top<=y_array[i]){ y_top=y_array[i]; }
if(y_bottom>=y_array[i]){ y_bottom=y_array[i]; }
}
}
makeTable(header, index, y_array.length, y_pixel, x_array[0], x_array[x_array.length-1], y_bottom, y_top);
}
function setGraph(header, index, x_array, y_array, type){
// same action with initGraph, but do again,
// because of I want to addListener after make All Graphs.
var y_pixel=100;
var y_top=100;
var y_bottom=0;
if(type == null || type != "percent"){
for(var i=0; i<y_array.length; i++){
if(i==0){ y_bottom=y_array[i]; y_top=y_array[i]; }
if(y_top<=y_array[i]){ y_top=y_array[i]; }
if(y_bottom>=y_array[i]){ y_bottom=y_array[i]; }
}
}
var y_dot = (y_top - y_bottom) / y_pixel;
if(y_dot <= 0){
return;
}
for(var i=0; i<y_array.length; i++){
var value = y_pixel - Math.round((y_array[i] - y_bottom) / y_dot);
for(var n=y_pixel; n>=value; n--){
setTable(index, i, n, x_array[i] + "<br>" + y_array[i]);
}
}
}
//---ここに必要な変数を追加or削除する---------------------------------------------------
document.addEventListener("DOMContentLoaded", function(){
// Title, any_ID, Array_for_X, Array_for_Y, Type[percent|null]
initGraph("$cpu_all_title", "cpu", cpu_all_x, cpu_all_y, "percent");
initGraph("$mem_use_title", "mem", mem_use_x, mem_use_y, "percent");
initGraph("$load_1m_title", "ld", load_1m_x, load_1m_y, null);
initGraph("$rxp_eth0_title", "rxp", rxp_eth0_x, rxp_eth0_y, null);
initGraph("$rxk_eth0_title", "rxk", rxp_eth0_x, rxk_eth0_y, null);
setGraph("$cpu_all_title", "cpu", cpu_all_x, cpu_all_y, "percent");
setGraph("$mem_use_title", "mem", mem_use_x, mem_use_y, "percent");
setGraph("$load_1m_title", "ld", load_1m_x, load_1m_y, null);
setGraph("$rxp_eth0_title", "rxp", rxp_eth0_x, rxp_eth0_y, null);
setGraph("$rxk_eth0_title", "rxk", rxp_eth0_x, rxk_eth0_y, null);
}, false);
var cpu_all_x = [$cpu_all_x];
var cpu_all_y = [$cpu_all_y];
var mem_use_x = [$mem_use_x];
var mem_use_y = [$mem_use_y];
var load_1m_x = [$load_1m_x];
var load_1m_y = [$load_1m_y];
var rxp_eth0_x = [$rxp_eth0_x];
var rxp_eth0_y = [$rxp_eth0_y];
var rxk_eth0_y = [$rxk_eth0_y];
//---(変数の追加 or 削除 ここまで)---------------------------------------------------
-->
</script>
</head>
<body>
<div id=HintDiv>now loading</div>
<h3>$SARINFO</h3>
</body>
</html>
EOS
`
printf "Content-type: text/html; charset=UTF-8\r\n"
printf "Content-Length: %d\r\n" `expr length "$body"`
printf "\r\n"
printf '%s' "$body"
printf "\r\n"
|
|