From 7acd010f20436143bbdb87de504d19c82eec411f Mon Sep 17 00:00:00 2001 From: Tom Angert Date: Sun, 21 Jul 2019 09:03:31 -0400 Subject: [PATCH 01/16] Add support for 5 minutes data --- index.php | 114 +++++++++++++++++++++++++++++++--------- vnstat.php | 149 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 198 insertions(+), 65 deletions(-) diff --git a/index.php b/index.php index 0eca23b..63ef1b5 100644 --- a/index.php +++ b/index.php @@ -86,18 +86,68 @@ function printTableStats($path, $type, $interface, $label) - + - - + + + +
diff --git a/vnstat.php b/vnstat.php index 33f48e2..95b3614 100644 --- a/vnstat.php +++ b/vnstat.php @@ -43,7 +43,7 @@ function bytesToString($bytes, $wSuf = false, $magnitude = null) } if ($wSuf == true) { - return sprintf("%0.4f", ($bytes / pow(1024, $ui))); + return sprintf("%0.6f", ($bytes / pow(1024, $ui))); } else { return sprintf("%0.2f %s", ($bytes / pow(1024, $ui)), $units[$ui]); } @@ -102,7 +102,7 @@ function getSmallestValue($array) function getLargestPrefix($bytes) { - $units = ['B', 'KB', 'MB', 'GB', 'TB']; + $units = ['B', 'K', 'M', 'G', 'T']; return $units[getMagnitude($bytes)]; } @@ -164,7 +164,7 @@ function getVnstatData($path, $type, $interface, $width = 800) if( $version > 1 ){ $i = 0; $j = 0; - $duration = floor(($width-200)/7); + $duration = floor(($width-200)/9); if ($duration < 40) { $duration = 40; } $duration = $duration * 180; foreach ($vnstatDecoded['interfaces'][0]['traffic']['fiveminute'] as $min) { @@ -204,7 +204,7 @@ function getVnstatData($path, $type, $interface, $width = 800) $daily[$i]['total'] = bytesToString($day['rx'] + $day['tx']); $daily[$i]['time'] = mktime(0, 0, 0, $day['date']['month'], $day['date']['day'], $day['date']['year']); - $dailyGraph[$i]['label'] = date('jS', mktime(0, 0, 0, $day['date']['month'], $day['date']['day'], $day['date']['year'])); + $dailyGraph[$i]['label'] = sprintf("Date(%d, %d, %d, %d, %d)",$day['date']['year'],$day['date']['month']-1,$day['date']['day'],0,0); $dailyGraph[$i]['rx'] = $day['rx']; $dailyGraph[$i]['tx'] = $day['tx']; $dailyGraph[$i]['total'] = ($day['rx'] + $day['tx']); From 079aa21fcff6c3d959cc0bfd4fe3e05ad6819c85 Mon Sep 17 00:00:00 2001 From: Tom Angert Date: Tue, 6 Aug 2019 22:54:16 -0400 Subject: [PATCH 06/16] Enable graph explorer Clean up base calculation --- index.php | 103 +++++++++++++++++++++++++++++++++++++++++------------ vnstat.php | 45 +++++++++++------------ 2 files changed, 104 insertions(+), 44 deletions(-) diff --git a/index.php b/index.php index 71d4481..e44c3e7 100644 --- a/index.php +++ b/index.php @@ -140,19 +140,30 @@ function drawFiveChart() if (isset($_COOKIE["width"])) { $width = $_COOKIE["width"]; } - $fiveGraph = getVnstatData($vnstat_cmd, "fiveGraph", $thisInterface, $width); + + // get duration in seconds for initial display based on screen width + $duration = floor(($width-200)/16); // number of samples + if ($duration < 24) { $duration = 24; } // minimum of 24 bar groups = 2 hours + $duration = $duration * 300; // in seconds + + $fiveGraph = getVnstatData($vnstat_cmd, "fiveGraph", $thisInterface); $fiveLargestValue = getLargestValue($fiveGraph); - $fiveSmallestValue = getSmallestValue($fiveGraph); $fiveLargestPrefix = getLargestPrefix($fiveLargestValue); $fiveMagnitude = getMagnitude($fiveLargestValue); + $fiveBase = getBaseValue($fiveGraph, $fiveMagnitude); $first = true; + $lastSample = 0; for ($i = 0; $i < count($fiveGraph); $i++) { $time = $fiveGraph[$i]['label']; $inTraffic = bytesToString($fiveGraph[$i]['rx'], true, $fiveMagnitude); $outTraffic = bytesToString($fiveGraph[$i]['tx'], true, $fiveMagnitude); $totalTraffic = bytesToString($fiveGraph[$i]['total'], true, $fiveMagnitude); + // can't just use duration/300 - there might be fewer or missing samples + if ($fiveGraph[0]['time'] - $fiveGraph[$i]['time'] < $duration) { + $lastSample = $i; + } if ($first) { $first = false; @@ -169,22 +180,28 @@ function drawFiveChart() title: 'Five minute Network Traffic', subtitle: 'over last 6 hours', orientation: 'horizontal', - bar: { groupWidth: '90%' }, + bar: { groupWidth: '85%' }, + explorer: { axis: 'horizontal', zoomDelta: 1.1, maxZoomIn: 0.10, maxZoomOut: 10 }, + legend: { position: 'bottom' }, chartArea: { left: 50, - width: '85%' + width: '95%' }, hAxis: { direction: -1, - format: 'H', + format: 'H:mm', minorGridlines: { count: 0 }, - title: 'Hour' + title: 'Hour:Minute', + viewWindow: { + min: new , + max: new + } }, vAxis: { format: '###.####', textStyle: { fontSize: 12 }, scaleType: 'log', - baseline: + baseline: } }; @@ -199,12 +216,23 @@ function drawHourlyChart() let data = google.visualization.arrayToDataTable([ [{type: 'datetime', label: 'Hour'}, 'Traffic In', 'Traffic Out', 'Total Traffic'], , + max: new + } }, vAxis: { format: '###.####', textStyle: { fontSize: 12 }, scaleType: 'log', - baseline: + baseline: } }; @@ -252,12 +292,23 @@ function drawDailyChart() let data = google.visualization.arrayToDataTable([ [{type: 'datetime', label: 'Date'}, 'Traffic In', 'Traffic Out', 'Total Traffic'], , + max: new + } }, vAxis: { format: '###.####', textStyle: { fontSize: 12 }, scaleType: 'log', - baseline: + baseline: } }; diff --git a/vnstat.php b/vnstat.php index 95b3614..6b1825b 100644 --- a/vnstat.php +++ b/vnstat.php @@ -76,11 +76,11 @@ function getLargestValue($array) }); } -function getSmallestValue($array) +function getBaseValue($array, $magnitude) { global $terraB; - $max = array_reduce($array, function ($a, $b) { + $sml = array_reduce($array, function ($a, $b) { if ((0 < $b['rx']) && ($b['rx'] < $b['tx'])) { $sml = $b['rx']; } else { @@ -93,11 +93,21 @@ function getSmallestValue($array) } }, $terraB); - if ($max < $terraB) { - return $max; + if ($sml >= $terraB) { + $sml = 1; } - return 1; + $base = pow(10,floor(round(log10($sml/pow(1024,$magnitude)),3))); + $baseByte = $base * pow(1024, $magnitude); + // if really close to smallest value use half so you can see the bar + if ($baseByte * 1.2 > $sml) { + $base = $base / 2; + // if smallest val is more than 6 times, use 5 times + } else if ($baseByte * 6 < $sml) { + $base = 5 * $base; + } + + return $base; } function getLargestPrefix($bytes) @@ -107,7 +117,7 @@ function getLargestPrefix($bytes) return $units[getMagnitude($bytes)]; } -function getVnstatData($path, $type, $interface, $width = 800) +function getVnstatData($path, $type, $interface) { global $version; @@ -163,10 +173,6 @@ function getVnstatData($path, $type, $interface, $width = 800) if( $version > 1 ){ $i = 0; - $j = 0; - $duration = floor(($width-200)/9); - if ($duration < 40) { $duration = 40; } - $duration = $duration * 180; foreach ($vnstatDecoded['interfaces'][0]['traffic']['fiveminute'] as $min) { if (is_array($min)) { ++$i; @@ -178,16 +184,11 @@ function getVnstatData($path, $type, $interface, $width = 800) $five[$i]['total'] = bytesToString($min['rx'] + $min['tx']); $five[$i]['time'] = mktime($min['time']['hour'], $min['time']['minute'], 0, $min['date']['month'], $min['date']['day'], $min['date']['year']); - if (time() - $five[$i]['time'] > $duration) { - continue; - } - ++$j; - - $fiveGraph[$j]['label'] = sprintf("Date(%d, %d, %d, %d, %d)",$min['date']['year'],$min['date']['month']-1,$min['date']['day'],$min['time']['hour'],$min['time']['minute']); - $fiveGraph[$j]['rx'] = $min['rx']; - $fiveGraph[$j]['tx'] = $min['tx']; - $fiveGraph[$j]['total'] = ($min['rx'] + $min['tx']); - $fiveGraph[$j]['time'] = mktime($min['time']['hour'], $min['time']['minute'], 0, $min['date']['month'], $min['date']['day'], $min['date']['year']); + $fiveGraph[$i]['label'] = sprintf("Date(%d, %d, %d, %d, %d)",$min['date']['year'],$min['date']['month']-1,$min['date']['day'],$min['time']['hour'],$min['time']['minute']); + $fiveGraph[$i]['rx'] = $min['rx']; + $fiveGraph[$i]['tx'] = $min['tx']; + $fiveGraph[$i]['total'] = ($min['rx'] + $min['tx']); + $fiveGraph[$i]['time'] = mktime($min['time']['hour'], $min['time']['minute'], 0, $min['date']['month'], $min['date']['day'], $min['date']['year']); } } } @@ -292,11 +293,11 @@ function getVnstatData($path, $type, $interface, $width = 800) case "five": return $five; case "hourlyGraph": - return array_slice($hourlyGraph, 0, 24, true); + return $hourlyGraph; case "hourly": return $hourly; case "dailyGraph": - return array_slice($dailyGraph, 0, 30, true); + return $dailyGraph; case "daily": return $daily; case "monthlyGraph": From a8ee57daf615805d29659e1505443d0bb1ca48c9 Mon Sep 17 00:00:00 2001 From: Tom Angert Date: Wed, 7 Aug 2019 20:48:09 -0400 Subject: [PATCH 07/16] Fix vnstat v1 compatibility Add zoom/pan instructions --- index.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/index.php b/index.php index e44c3e7..dd50adc 100644 --- a/index.php +++ b/index.php @@ -191,11 +191,13 @@ function drawFiveChart() direction: -1, format: 'H:mm', minorGridlines: { count: 0 }, - title: 'Hour:Minute', - viewWindow: { - min: new , - max: new - } + title: 'Hour:Minute Scroll to zoom, Drag to pan' + 0) { + echo ", viewWindow: {"; + echo "min: new " . $fiveGraph[$lastSample]['label'] . ", "; + echo "max: new " . $fiveGraph[0]['label']; + echo "}"; + } ?> }, vAxis: { format: '###.####', @@ -269,7 +271,7 @@ function drawHourlyChart() direction: -1, format: 'd:H', minorGridlines: { count: 0 }, - title: 'Day:Hour', + title: 'Day:Hour Scroll to zoom, Drag to pan', viewWindow: { min: new , max: new @@ -346,7 +348,7 @@ function drawDailyChart() direction: -1, format: 'M/d', //minorGridlines: { count: 0 }, - title: 'Date: Month/Day', + title: 'Month/Day Scroll to zoom, Drag to pan', viewWindow: { min: new , max: new From c112999e8197555ef3ed2b70036952619bc408c6 Mon Sep 17 00:00:00 2001 From: Tom Angert Date: Fri, 9 Aug 2019 10:52:27 -0400 Subject: [PATCH 08/16] Merge main with: support for vnstat v2 support for 5 minute data vnstat v1 compatible So far - graph in first tab is OK, other tabs are small and incomplete --- {css => app/assets/css}/style.css | 0 config.php => app/include/config.php | 0 vnstat.php => app/include/vnstat.php | 0 index.php => app/index.php | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {css => app/assets/css}/style.css (100%) rename config.php => app/include/config.php (100%) rename vnstat.php => app/include/vnstat.php (100%) rename index.php => app/index.php (100%) diff --git a/css/style.css b/app/assets/css/style.css similarity index 100% rename from css/style.css rename to app/assets/css/style.css diff --git a/config.php b/app/include/config.php similarity index 100% rename from config.php rename to app/include/config.php diff --git a/vnstat.php b/app/include/vnstat.php similarity index 100% rename from vnstat.php rename to app/include/vnstat.php diff --git a/index.php b/app/index.php similarity index 100% rename from index.php rename to app/index.php From 466cdf084ca1393ead23faf19fe7cfd1e160922e Mon Sep 17 00:00:00 2001 From: Tom Angert Date: Fri, 9 Aug 2019 10:54:04 -0400 Subject: [PATCH 09/16] Merge main with: support for vnstat v2 support for 5 minute data vnstat v1 compatible So far - graph in first tab is OK, other tabs are small and incomplete --- app/assets/css/style.css | 2 +- app/include/config.php | 5 +- app/include/vnstat.php | 25 ++++-- app/index.php | 182 +++++++++++++++++++++++++++------------ 4 files changed, 147 insertions(+), 67 deletions(-) diff --git a/app/assets/css/style.css b/app/assets/css/style.css index 6e35c81..2daa638 100644 --- a/app/assets/css/style.css +++ b/app/assets/css/style.css @@ -1,5 +1,5 @@ /* -Copyright (C) 2016 Alex +Copyright (C) 2019 Alexander Marston (alexander.marston@gmail.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/app/include/config.php b/app/include/config.php index 4d1e6cd..98a5991 100644 --- a/app/include/config.php +++ b/app/include/config.php @@ -1,7 +1,7 @@ . */ +// Disable error reporting +error_reporting(0); + // Set the default system Timezone date_default_timezone_set('Europe/London'); diff --git a/app/include/vnstat.php b/app/include/vnstat.php index 6b1825b..774bdf8 100644 --- a/app/include/vnstat.php +++ b/app/include/vnstat.php @@ -1,7 +1,7 @@ $sml) { - $base = $base / 2; - // if smallest val is more than 6 times, use 5 times - } else if ($baseByte * 6 < $sml) { - $base = 5 * $base; + + // google chart sometimes refuses to draw y axis units when base is 5*10^x + + //if ($sml / $baseByte < 1.2) { + // $base = $base / 2; + // if smallest val is more than 6 times, use 5 times so smallest bar is not so big + //} else if ($sml / $baseByte > 6 ) { + // $base = 5 * $base; + //} + + if ($sml / $baseByte < 1.05) { + $base = $base / 10; } return $base; } -function getLargestPrefix($bytes) +function getLargestPrefix($magnitude) { $units = ['B', 'K', 'M', 'G', 'T']; - return $units[getMagnitude($bytes)]; + return $units[$magnitude]; } function getVnstatData($path, $type, $interface) diff --git a/app/index.php b/app/index.php index dd50adc..4fd3ca0 100644 --- a/app/index.php +++ b/app/index.php @@ -1,6 +1,6 @@ . */ -require('vnstat.php'); // The vnstat information parser -require('config.php'); // Include all the configuration information +require('includes/vnstat.php'); // The vnstat information parser +require('includes/config.php'); // Include all the configuration information function printOptions() { @@ -90,15 +90,17 @@ function printTableStats($path, $type, $interface, $label) Network Traffic - + - - - + + + + + - - + + - -
- -
-