vnstat.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. <?php
  2. /*
  3. * Copyright (C) 2019 Alexander Marston ([email protected])
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. class vnStat {
  19. protected $executablePath;
  20. protected $vnstatVersion;
  21. protected $vnstatJsonVersion;
  22. protected $vnstatData;
  23. public function __construct ($executablePath) {
  24. if (isset($executablePath)) {
  25. $this->executablePath = $executablePath;
  26. // Execute a command to output a json dump of the vnstat data
  27. $vnstatStream = popen("$this->executablePath --json", 'r');
  28. // Is the stream valid?
  29. if (is_resource($vnstatStream)) {
  30. $streamBuffer = '';
  31. while (!feof($vnstatStream)) {
  32. $streamBuffer .= fgets($vnstatStream);
  33. }
  34. // Close the handle
  35. pclose($vnstatStream);
  36. $this->processVnstatData($streamBuffer);
  37. } else {
  38. }
  39. } else {
  40. die();
  41. }
  42. }
  43. private function processVnstatData($vnstatJson) {
  44. $decodedJson = json_decode($vnstatJson, true);
  45. // Check the JSON is valid
  46. if (json_last_error() != JSON_ERROR_NONE) {
  47. throw new Exception('JSON is invalid');
  48. }
  49. $this->vnstatData = $decodedJson;
  50. $this->vnstatVersion = $decodedJson['vnstatversion'];
  51. $this->vnstatJsonVersion = $decodedJson['jsonversion'];
  52. }
  53. public function getVnstatVersion() {
  54. return $this->vnstatVersion;
  55. }
  56. public function getVnstatJsonVersion() {
  57. return $this->vnstatJsonVersion;
  58. }
  59. public function getInterfaces() {
  60. // Create a placeholder array
  61. $vnstatInterfaces = [];
  62. foreach($this->vnstatData['interfaces'] as $interface) {
  63. if ($this->vnstatJsonVersion == 1) {
  64. array_push($vnstatInterfaces, $interface['id']);
  65. } else {
  66. array_push($vnstatInterfaces, $interface['name']);
  67. }
  68. }
  69. return $vnstatInterfaces;
  70. }
  71. public function getInterfaceData($timeperiod, $type, $interface) {
  72. // If json version equals 1, add an 's' onto the end of each type.
  73. // e.g. 'top' becomes 'tops'
  74. $typeAppend = '';
  75. if ($this->vnstatJsonVersion == 1) {
  76. $typeAppend = 's';
  77. }
  78. // Blank placeholder
  79. $trafficData = [];
  80. $i = -1;
  81. // Get the array index for the chosen interface
  82. if ($this->vnstatJsonVersion == 1) {
  83. $arrayIndex = array_search($interface, array_column($this->vnstatData['interfaces'], 'id'));
  84. } else {
  85. $arrayIndex = array_search($interface, array_column($this->vnstatData['interfaces'], 'name'));
  86. }
  87. if ($timeperiod == 'top10') {
  88. if ($type == 'table') {
  89. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['top'.$typeAppend] as $traffic) {
  90. if (is_array($traffic)) {
  91. $i++;
  92. $trafficData[$i]['label'] = date('d/m/Y', strtotime($traffic['date']['month'] . "/" . $traffic['date']['day'] . "/" . $traffic['date']['year']));;
  93. $trafficData[$i]['rx'] = formatSize($traffic['rx'], $this->vnstatJsonVersion);
  94. $trafficData[$i]['tx'] = formatSize($traffic['tx'], $this->vnstatJsonVersion);
  95. $trafficData[$i]['total'] = formatSize(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  96. $trafficData[$i]['totalraw'] = ($traffic['rx'] + $traffic['tx']);
  97. }
  98. }
  99. }
  100. }
  101. if (($this->vnstatJsonVersion > 1) && ($timeperiod == 'five')) {
  102. if ($type == 'table') {
  103. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['fiveminute'] as $traffic) {
  104. if (is_array($traffic)) {
  105. $i++;
  106. $trafficData[$i]['label'] = date("d/m/Y H:i", mktime($traffic['time']['hour'], $traffic['time']['minute'], 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']));
  107. $trafficData[$i]['time'] = mktime($traffic['time']['hour'], $traffic['time']['minute'], 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  108. $trafficData[$i]['rx'] = formatSize($traffic['rx'], $this->vnstatJsonVersion);
  109. $trafficData[$i]['tx'] = formatSize($traffic['tx'], $this->vnstatJsonVersion);
  110. $trafficData[$i]['total'] = formatSize(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  111. }
  112. }
  113. } else if ($type == 'graph') {
  114. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['fiveminute'] as $traffic) {
  115. if (is_array($traffic)) {
  116. $i++;
  117. $trafficData[$i]['label'] = sprintf("Date(%d, %d, %d, %d, %d)", $traffic['date']['year'], $traffic['date']['month']-1, $traffic['date']['day'], $traffic['time']['hour'], $traffic['time']['minute']);
  118. $trafficData[$i]['time'] = mktime($traffic['time']['hour'], $traffic['time']['minute'], 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  119. $trafficData[$i]['rx'] = kibibytesToBytes($traffic['rx'], $this->vnstatJsonVersion);
  120. $trafficData[$i]['tx'] = kibibytesToBytes($traffic['tx'], $this->vnstatJsonVersion);
  121. $trafficData[$i]['total'] = kibibytesToBytes(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  122. }
  123. }
  124. }
  125. }
  126. if ($timeperiod == 'hourly') {
  127. if ($type == 'table') {
  128. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['hour'.$typeAppend] as $traffic) {
  129. if (is_array($traffic)) {
  130. $i++;
  131. if ($this->vnstatJsonVersion == 1) {
  132. $hour = $traffic['id'];
  133. } else {
  134. $hour = $traffic['time']['hour'];
  135. }
  136. $trafficData[$i]['label'] = date("d/m/Y H:i", mktime($hour, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']));
  137. $trafficData[$i]['time'] = mktime($hour, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  138. $trafficData[$i]['rx'] = formatSize($traffic['rx'], $this->vnstatJsonVersion);
  139. $trafficData[$i]['tx'] = formatSize($traffic['tx'], $this->vnstatJsonVersion);
  140. $trafficData[$i]['total'] = formatSize(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  141. }
  142. }
  143. } else if ($type == 'graph') {
  144. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['hour'.$typeAppend] as $traffic) {
  145. if (is_array($traffic)) {
  146. $i++;
  147. if ($this->vnstatJsonVersion == 1) {
  148. $hour = $traffic['id'];
  149. } else {
  150. $hour = $traffic['time']['hour'];
  151. }
  152. $trafficData[$i]['label'] = sprintf("Date(%d, %d, %d, %d)", $traffic['date']['year'], $traffic['date']['month']-1, $traffic['date']['day'], $hour);
  153. $trafficData[$i]['time'] = mktime($hour, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  154. $trafficData[$i]['rx'] = kibibytesToBytes($traffic['rx'], $this->vnstatJsonVersion);
  155. $trafficData[$i]['tx'] = kibibytesToBytes($traffic['tx'], $this->vnstatJsonVersion);
  156. $trafficData[$i]['total'] = kibibytesToBytes(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  157. }
  158. }
  159. }
  160. }
  161. if ($timeperiod == 'daily') {
  162. if ($type == 'table') {
  163. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['day'.$typeAppend] as $traffic) {
  164. if (is_array($traffic)) {
  165. $i++;
  166. $trafficData[$i]['label'] = date('d/m/Y', mktime(0, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']));
  167. $trafficData[$i]['time'] = mktime(0, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  168. $trafficData[$i]['rx'] = formatSize($traffic['rx'], $this->vnstatJsonVersion);
  169. $trafficData[$i]['tx'] = formatSize($traffic['tx'], $this->vnstatJsonVersion);
  170. $trafficData[$i]['total'] = formatSize(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  171. }
  172. }
  173. } else if ($type == 'graph') {
  174. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['day'.$typeAppend] as $traffic) {
  175. if (is_array($traffic)) {
  176. $i++;
  177. $trafficData[$i]['label'] = sprintf("Date(%d, %d, %d)", $traffic['date']['year'], $traffic['date']['month']-1, $traffic['date']['day']);
  178. $trafficData[$i]['time'] = mktime(0, 0, 0, $traffic['date']['month'], $traffic['date']['day'], $traffic['date']['year']);
  179. $trafficData[$i]['rx'] = kibibytesToBytes($traffic['rx'], $this->vnstatJsonVersion);
  180. $trafficData[$i]['tx'] = kibibytesToBytes($traffic['tx'], $this->vnstatJsonVersion);
  181. $trafficData[$i]['total'] = kibibytesToBytes(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  182. }
  183. }
  184. }
  185. }
  186. if ($timeperiod == 'monthly') {
  187. if ($type == 'table') {
  188. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['month'.$typeAppend] as $traffic) {
  189. if (is_array($traffic)) {
  190. $i++;
  191. $trafficData[$i]['label'] = date('F Y', mktime(0, 0, 0, $traffic['date']['month'], 10, $traffic['date']['year']));
  192. $trafficData[$i]['time'] = mktime(0, 0, 0, $traffic['date']['month'], 10, $traffic['date']['year']);
  193. $trafficData[$i]['rx'] = formatSize($traffic['rx'], $this->vnstatJsonVersion);
  194. $trafficData[$i]['tx'] = formatSize($traffic['tx'], $this->vnstatJsonVersion);
  195. $trafficData[$i]['total'] = formatSize(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  196. }
  197. }
  198. } else if ($type == 'graph') {
  199. foreach ($this->vnstatData['interfaces'][$arrayIndex]['traffic']['month'.$typeAppend] as $traffic) {
  200. if (is_array($traffic)) {
  201. $i++;
  202. $trafficData[$i]['label'] = sprintf("Date(%d, %d, %d)", $traffic['date']['year'], $traffic['date']['month'] - 1, 10);
  203. $trafficData[$i]['time'] = mktime(0, 0, 0, $traffic['date']['month'], 10, $traffic['date']['year']);
  204. $trafficData[$i]['rx'] = kibibytesToBytes($traffic['rx'], $this->vnstatJsonVersion);
  205. $trafficData[$i]['tx'] = kibibytesToBytes($traffic['tx'], $this->vnstatJsonVersion);
  206. $trafficData[$i]['total'] = kibibytesToBytes(($traffic['rx'] + $traffic['tx']), $this->vnstatJsonVersion);
  207. }
  208. }
  209. }
  210. }
  211. if ($timeperiod != 'top10') {
  212. usort($trafficData, 'sortingFunction');
  213. }
  214. if ($type == 'graph') {
  215. // Get the largest value and then prefix (B, KB, MB, GB, etc)
  216. $trafficLargestValue = getLargestValue($trafficData);
  217. $trafficScale = getScale($trafficLargestValue);
  218. $trafficLargestPrefix = getLargestPrefix($trafficScale);
  219. $trafficBase = getBaseValue($trafficData, $trafficScale);
  220. if (($trafficBase < .0099) && ($trafficScale >= 1))
  221. {
  222. $trafficScale = $trafficScale - 1;
  223. $trafficLargestPrefix = getLargestPrefix($trafficScale);
  224. $trafficBase = getBaseValue($trafficData, $trafficScale);
  225. }
  226. foreach($trafficData as &$value) {
  227. $value['rx'] = formatBytesTo($value['rx'], $trafficScale);
  228. $value['tx'] = formatBytesTo($value['tx'], $trafficScale);
  229. $value['total'] = formatBytesTo($value['total'], $trafficScale);
  230. }
  231. unset($value);
  232. $trafficData[0]['delimiter'] = $trafficLargestPrefix;
  233. $trafficData[0]['base'] = $trafficBase;
  234. }
  235. return $trafficData;
  236. }
  237. }
  238. ?>