SNMPで取得したネットワーク機器のトラフィック情報をもとに、JavaScriptを利用してトラフィックグラフを表示するツールを作成します。
トラフィック情報の取得方法については、下記を参照してください。
- Progate 〜 プログラミングの入門なら基礎から学べるProgate[プロゲート]
- ドットインストール 〜 3分動画でマスターできるプログラミング学習サービス
どちらのサイトも無料で学習可能な範囲があります。有料コンテンツに関しては、月額1000円程度です。
目標作成物
ブラウザ上でCSVファイルを読み込み、トラフィックグラフを表示します。
初期画面
CSVファイルの読み込み後
以下の機能を持たせています。
- CSVファイルの読み込み
- ファイル選択ダイアログを開き、CSVファイルを指定します。
- 表示する期間の指定
- 表示対象の期間を指定します。
- グラフの上限値の変更(100Mbps〜1Kbps)
- デフォルトで上限100Mbpsとして、1Kbpsまで調整可能とします。
作成準備
利用する技術
今回利用する技術は下記の通りです。
- HTML
- Webページを作成するための言語
- CSS
- Webページの見た目を整える
- JavaScript
- Webブラウザ上で動作するプログラミング言語
- Bootstrap
- Webアプリケーション用のフレームワーク
- Chart.js
- JavaScriptでグラフを描くライブラリ
トラフィック情報(CSVデータ)
「日付」「時刻」「Input(総送信Byte数)」「Output(総受信Byte数)」をカラム区切りで記載したCSVファイルを読み込みます。データは、1分毎に取得しています。
date,time,In,Out
2022/8/18,17:59:00,1113152536,1113073622
2022/8/18,18:00:00,1235056092,1164996546
2022/8/18,18:01:00,1535296858,1225215608
・・・
・・・
今回利用するデータの全量は下記です。
クリックしてCSVファイル全体を表示
date,time,In,Out
2022/8/18,17:59:00,1113152536,1113073622
2022/8/18,18:00:00,1235056092,1164996546
2022/8/18,18:01:00,1535296858,1225215608
2022/8/18,18:02:01,1845412770,1295330405
2022/8/18,18:03:00,2245528622,1395445125
2022/8/18,18:04:00,2625844594,1515759785
2022/8/18,18:05:00,2935846446,1615760505
2022/8/18,18:06:00,3435848298,1765761225
2022/8/18,18:07:00,3876664090,1906575945
2022/8/18,18:08:01,4396666002,2086576665
2022/8/18,18:09:00,4936667914,2286577385
2022/8/18,18:10:00,5496669766,2496578105
2022/8/18,18:11:00,5917085618,2676992825
2022/8/18,18:12:00,6327087530,2866993545
2022/8/18,18:13:00,6697089622,3006994342
2022/8/18,18:14:00,7017092434,3176995002
2022/8/18,18:15:00,7357097646,3336995722
2022/8/18,18:16:00,7657101178,3516996442
2022/8/18,18:17:00,7927103090,3636997162
2022/8/18,18:18:01,8217105002,3726997882
2022/8/18,18:19:00,8487106914,3826998602
2022/8/18,18:20:00,8727108946,3906999382
2022/8/18,18:21:00,8947110738,3977000102
2022/8/18,18:22:01,9127112602,4057000822
2022/8/18,18:23:00,9327114454,4117001542
2022/8/18,18:24:00,9477116486,4167002339
2022/8/18,18:25:01,9637118278,4207003059
2022/8/18,18:26:00,9817120070,4277003779
2022/8/18,18:27:00,10007121982,4377004499
2022/8/18,18:28:00,10147123954,4427005219
2022/8/18,18:29:01,10237125866,4481005939
2022/8/18,18:30:00,10317127778,4525006599
2022/8/18,18:31:00,10567129570,4587007319
2022/8/18,18:32:00,10807131482,4672008039
2022/8/18,18:33:00,11087133514,4787008759
2022/8/18,18:34:00,11487135426,4917009556
2022/8/18,18:35:01,11927137338,5077010276
2022/8/18,18:36:00,12457139190,5263010996
2022/8/18,18:37:00,12957141102,5457011716
2022/8/18,18:38:00,13477142954,5677012436
2022/8/18,18:39:00,13987144866,5927013156
2022/8/18,18:40:00,14597146778,6137013936
2022/8/18,18:41:01,15187148570,6437014656
2022/8/18,18:42:00,15837150374,6787015316
2022/8/18,18:43:01,16517152226,7197016053
2022/8/18,18:44:00,17177154138,7597016713
2022/8/18,18:45:00,17767156050,7937017433
2022/8/18,18:46:00,18327157794,8127018093
2022/8/18,18:47:00,18827159826,8327018813
2022/8/18,18:48:00,19367161738,8512019533
2022/8/18,18:49:01,19877163650,8682020193
2022/8/18,18:50:00,20327165622,8817020913
2022/8/18,18:51:00,20797167474,8927021633
2022/8/18,18:52:00,21197169326,9107022353
2022/8/18,18:53:00,21537171298,9284023073
2022/8/18,18:54:00,21847173270,9427023793
2022/8/18,18:55:00,22137175182,9567024590
2022/8/18,18:56:01,22387177034,9687025310
2022/8/18,18:57:00,22627178946,9824026030
2022/8/18,18:58:00,22817517908,9917371076
2022/8/18,18:59:00,23017934580,10001784344
2022/8/18,19:00:00,23198040634,10065884190
トラフィック情報の取得方法は、下記を参照してください。
プログラムの全体像
プログラムの完成形は下記です。「index.html(HTMLファイル)」と「main.js(JavaScriptコード)」の2ファイルを用意して、「index.html」をブラウザで開けば動作します。
クリックしてHTMLファイル全体を表示
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Traffic Graph</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
</head>
<body>
<body class="bg-light">
<div class="container w-75">
<h1 class="text-center py-1 my-2 bg-dark text-white font-monospace">Traffic Graph Display Tool</h1>
<form id="form" class="mb-2">
<div class="mb-3">
<label for="formFile" class="form-label text-primary">表示するI/Fのファイルを選択してください</label>
<input class="form-control font-monospace" type="file" id="file">
</div>
<div class="text-primary mt-2">表示する期間を選択してください</div>
<div class="datetime-check font-monospace">
<input type="datetime-local" id="start-time" name="start-time" step="300">
〜
<input type="datetime-local" id="end-time" name="end-time" step="300">
<button type="button" id="display" class="btn btn-primary my-1">表示</button>
</div>
<div class="text-primary my-2">グラフの上限値を変更できます。(デフォルト=100Mbps)</div>
<button type="button" id="100M" value="M,100,10" onclick="bpscalc(this)"
class="btn btn-secondary">100Mbps</button>
<button type="button" id="10M" value="M,10,1" onclick="bpscalc(this)"
class="btn btn-secondary">10Mbps</button>
<button type="button" id="1M" value="M,1,1" onclick="bpscalc(this)"
class="btn btn-secondary">1Mbps</button>
<button type="button" id="100K" value="K,100,10" onclick="bpscalc(this)"
class="btn btn-secondary">100Kbps</button>
<button type="button" id="10K" value="k,10,1" onclick="bpscalc(this)"
class="btn btn-secondary">10Kbps</button>
<button type="button" id="1K" value="K,1,1" onclick="bpscalc(this)"
class="btn btn-secondary">1Kbps</button>
</form>
<canvas id="trafficGraph"></canvas>
</div>
</body>
<script src="main.js"></script>
</html>
JavaScriptのコードに関しては、少し冗長な書き方になっていますが、「CSVファイルを読み込んだ時の処理」「表示期間を指定した時の処理」「グラフ上限値を変更した時の処理」に分けて記載しています。
HTMLファイルの詳細説明
HTMLファイルの詳細を説明します。
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
Bootstrapを利用するための記述です。
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
Chart.jsを利用するための記述です。
<div class="mb-3">
<label for="formFile" class="form-label text-primary">表示するI/Fのファイルを選択してください</label>
<input class="form-control font-monospace" type="file" id="file">
</div>
CSVファイルを取得するためのフィールドを設置します。
<div class="text-primary mt-2">表示する期間を選択してください</div>
<div class="datetime-check font-monospace">
<input type="datetime-local" id="start-time" name="start-time" step="300">
〜
<input type="datetime-local" id="end-time" name="end-time" step="300">
<button type="button" id="display" class="btn btn-primary my-1">表示</button>
</div>
表示する期間を指定するためのフィールドを設置します。
<div class="text-primary my-2">グラフの上限値を変更できます。(デフォルト=100Mbps)</div>
<button type="button" id="100M" value="M,100,10" onclick="bpscalc(this)"
class="btn btn-secondary">100Mbps</button>
<button type="button" id="10M" value="M,10,1" onclick="bpscalc(this)"
class="btn btn-secondary">10Mbps</button>
<button type="button" id="1M" value="M,1,1" onclick="bpscalc(this)"
class="btn btn-secondary">1Mbps</button>
<button type="button" id="100K" value="K,100,10" onclick="bpscalc(this)"
class="btn btn-secondary">100Kbps</button>
<button type="button" id="10K" value="k,10,1" onclick="bpscalc(this)"
class="btn btn-secondary">10Kbps</button>
<button type="button" id="1K" value="K,1,1" onclick="bpscalc(this)"
class="btn btn-secondary">1Kbps</button>
グラフ上限値を変更するためのボタンを設置します。押したボタンによって処理を変えるために、”value” を設定します。
<canvas id="trafficGraph"></canvas>
グラフを描画するためのフィールドを定義します。
<script src="main.js"></script>
JavaScriptを呼び出します。
JavaScriptコードの詳細説明
JavaScriptコードの詳細を説明します。
CSVファイルを読み込んだ時の処理
const ctx = document.getElementById("trafficGraph");
let trafficGraph = new Chart(ctx);
グラフ描画用の変数をセットします。
const result = [];
let fileInput = document.getElementById('file');
let fileReader = new FileReader();
fileInput.onchange = () => {
let file = fileInput.files[0];
fileReader.readAsText(file);
};
CSVファイルを読み込み、変数にセットします。
fileReader.onload = () => {
const txt = fileReader.result;
const arr = txt.split("\n");
for (let i = 0; i < arr.length; ++i) {
result[i] = arr[i].split(',');
}
CSVファイルを、カンマ区切りで配列(result)に格納します。
const datetime = [];
const input5minave = [];
const output5minave = [];
グラフの要素を配列として宣言します。
for (let i = 0; i < result.length - 1; i++) {
CSVファイルの行数分、繰り返し処理を開始します。
datetime[i] = result[i][0] + ' ' + result[i][1].slice(0, -3);
「日付」と「時刻」を結合して、配列(datetime)に格納します。
input5minave[i] = (Number(result[i + 1][2]) - Number(result[i][2])) / 1024 / 1024 * 8 / 60;
output5minave[i] = (Number(result[i + 1][3]) - Number(result[i][3])) / 1024 / 1024 * 8 / 60;
}
送受信データ量については以下の計算をして、配列(input5minave/output5minave)に格納します。
- (Number(result[i + 1][2]) – Number(result[i][2]))
- 2回分のデータの差分を計算し、1分間の送受信データ量を取得
- / 1024 / 1024
- 1024で2回割り、メガへ変換
- * 8
- 8を掛けて、Byte→bitへ変換
- / 60
- 60で割って、1秒あたりの平均速度を計算(per/secの計算)
datetime.shift();
input5minave.shift();
output5minave.shift();
それぞれの配列の見出し行を削除します。
let sdateelement = document.getElementById("start-time");
let edateelement = document.getElementById("end-time");
const starttime = new Date(datetime[0]);
starttime.setHours(starttime.getHours() + 9)
sdateelement.value = starttime.toISOString().slice(0, -8);
const endtime = new Date(datetime[datetime.length - 1]);
endtime.setHours(endtime.getHours() + 9)
edateelement.value = endtime.toISOString().slice(0, -8);
CSVファイルの開始日時と終了日時を取得し、ツール上の「表示期間選択フィールド」にセットします。
if (trafficGraph) {
trafficGraph.destroy();
}
変数:trafficGraphのデータをリセットします。※この処理を入れないと、グラフを再描画した際に表示が乱れることがあります。
trafficGraph = new Chart(ctx, {
グラフ描画用の変数に表示する値をセットします。
type: 'line',
「折れ線グラフ」を指定します。
data: {
labels: datetime,
横軸に日時(配列:datetime)をセットします。
datasets: [
{
label: 'Input',
data: input5minave,
borderColor: "rgba(175,215,246,1)",
backgroundColor: "rgba(0,0,0,0)"
},
縦軸の1つ目に受信平均速度(配列:input5minave)をセットし、線の色を指定します。
{
label: 'Output',
data: output5minave,
borderColor: "rgba(237,192,58,1)",
backgroundColor: "rgba(0,0,0,0)"
}
縦軸の2つ目に送信平均速度(配列:output5minave)をセットし、線の色を指定します。
options: {
title: {
display: false,
text: 'トラフィックグラフ'
},
グラフのタイトルを指定します。※今回は、”false” を指定して、非表示にしています。
scales: {
yAxes: [{
ticks: {
max: 100,
min: 0,
stepSize: 10,
「グラフ上限値」「下限値」「補助メモリの間隔」を指定します。
scaleLabel: {
display: true,
labelString: 'Mbps'
縦軸のラベルを指定します。
動作確認(CSVファイルの読み込み)
表示期間を指定した時の処理
let displayclick = document.getElementById('display');
「表示」ボタンのIDを取得します。
displayclick.onclick = () => {
「表示」ボタンをクリックした時の関数を定義します。
const starttime = new Date(document.getElementById('start-time').value);
const endtime = new Date(document.getElementById('end-time').value);
表示する期間の「開始日時」と「終了日時」を取得します。
let specstarttime = 0;
let specendtime = datetime.length;
指定された表示期間を特定するための変数を定義します。
for (var i = 0; i < datetime.length - 1; i++) {
datetimediff = new Date(datetime[i]);
if (starttime.getTime() <= datetimediff.getTime()) {
specstarttime = i;
break;
}
}
横軸(配列:datetime)の何番目から表示するかを特定します。
for (var i = 0; i < datetime.length - 1; i++) {
datetimediff = new Date(datetime[i]);
if (endtime.getTime() <= datetimediff.getTime()) {
specendtime = i;
break;
}
}
横軸(配列:datetime)の何番目まで表示するかを特定します。
const specdatetime = datetime.slice(specstarttime, specendtime + 1);
const specinput5minave = input5minave.slice(specstarttime, specendtime + 1);
const specoutput5minave = output5minave.slice(specstarttime, specendtime + 1);
特定した表示期間で、グラフの要素を切り取ります。
if (trafficGraph) {
trafficGraph.destroy();
}
変数:trafficGraphのデータをリセットします。※この処理を入れないと、グラフを再描画した際に表示が乱れることがあります。
trafficGraph = new Chart(ctx, {
labels: specdatetime,
data: specinput5minave,
data: specoutput5minave,
特定した表示期間で、グラフを描画します。
動作確認(表示期間の変更)
グラフ上限値を変更した時の処理
objvalue = obj.value.split(",");
上限値を指定するボタンのvalueの値をカンマ区切りで取得します。
if (objvalue[0] == "M") {
for (let i = 0; i < result.length - 1; i++) {
datetime[i] = result[i][0] + ' ' + result[i][1].slice(0, -3);
input5minave[i] = (Number(result[i + 1][2]) - Number(result[i][2])) / 1024 / 1024 * 8 / 60;
output5minave[i] = (Number(result[i + 1][3]) - Number(result[i][3])) / 1024 / 1024 * 8 / 60;
}
Mbpsのボタンが押された場合の処理です。
} else {
for (var i = 0; i < result.length - 1; i++) {
datetime[i] = result[i][0] + ' ' + result[i][1].slice(0, -3);
input5minave[i] = (Number(result[i + 1][2]) - Number(result[i][2])) / 1024 * 8 / 60;
output5minave[i] = (Number(result[i + 1][3]) - Number(result[i][3])) / 1024 * 8 / 60;
}
}
Kbpsのボタンが押された場合の処理です。※1024で割る回数を1回にして、Kbpsを計算しています。
trafficGraph = new Chart(ctx, {
labelString: objvalue[0] + 'bps'
MbpsかKbpsによって、表示を変えています。
動作確認(グラフ上限値の変更)
以上で、ネットワークエンジニアのプログラミング【JavaScript入門(トラフィックグラフ作成)】の説明は完了です!プログラミングができると、仕事の効率化ができますし、何より仕事を楽しむことができます!!
- Progate 〜 プログラミングの入門なら基礎から学べるProgate[プロゲート]
- ドットインストール 〜 3分動画でマスターできるプログラミング学習サービス
どちらのサイトも無料で学習可能な範囲があります。有料コンテンツに関しては、月額1000円程度です。