api.ophanimgraph.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <?php
  2. /**
  3. * Performs charts data preprocessing and rendering
  4. */
  5. class OphanimGraph {
  6. /**
  7. * Default graphs interval
  8. *
  9. * @var int
  10. */
  11. protected $interval = 300;
  12. /**
  13. * Custom graphs palette
  14. *
  15. * @var string
  16. */
  17. protected $palette = 'OphanimFlow';
  18. /**
  19. * Bandwidthd-like legacy custom palette overrides
  20. *
  21. * @var array
  22. */
  23. protected $colorOverrides = array(
  24. 1 => array('r' => 240, 'g' => 0, 'b' => 0),
  25. 2 => array('r' => 140, 'g' => 0, 'b' => 0),
  26. 3 => array('r' => 0, 'g' => 220, 'b' => 0),
  27. 5 => array('r' => 252, 'g' => 93, 'b' => 0),
  28. 6 => array('r' => 240, 'g' => 240, 'b' => 0),
  29. 7 => array('r' => 174, 'g' => 174, 'b' => 174),
  30. 8 => array('r' => 0, 'g' => 0, 'b' => 245),
  31. 11 => array('r' => 54, 'g' => 49, 'b' => 22),
  32. );
  33. /**
  34. * Charts debug flag
  35. *
  36. * @var bool
  37. */
  38. protected $debug = true;
  39. /**
  40. * Accurate charts instead of maximum performance flag
  41. *
  42. * @var bool
  43. */
  44. protected $accurateFlag = false;
  45. public function __construct() {
  46. global $ubillingConfig;
  47. $this->debug = $ubillingConfig->getAlterParam('CHARTS_DEBUG');
  48. $this->accurateFlag = $ubillingConfig->getAlterParam('CHARTS_ACCURATE');
  49. }
  50. /**
  51. * Converts byte counters into speed in Mbit/s for 5 mins
  52. *
  53. * @param int $bytes
  54. * @param bool $check
  55. *
  56. * @return float
  57. */
  58. public function bytesToSpeed($bytes, $check = false) {
  59. $result = 0;
  60. if ($check) {
  61. if (!is_numeric($bytes)) {
  62. $bytes = trim($bytes);
  63. }
  64. }
  65. if ($bytes != 0) {
  66. $result = ($bytes * 8) / $this->interval / 1048576; //mbits per 5 minutes
  67. }
  68. return ($result);
  69. }
  70. /**
  71. * Converts byte counters into Mbytes
  72. *
  73. * @param int $bytes
  74. *
  75. * @return float
  76. */
  77. public function bytesToMb($bytes) {
  78. $result = 0;
  79. if ($bytes != 0) {
  80. $result = $bytes / 1048576; //mbytes
  81. }
  82. return ($result);
  83. }
  84. /**
  85. * Returns raw chart data as array of filtered by date record lines
  86. *
  87. * @param string $ip
  88. * @param string $direction
  89. * @param string $dateFrom
  90. * @param string $dateTo
  91. *
  92. * @return array
  93. */
  94. public function getChartData($ip, $direction, $dateFrom, $dateTo) {
  95. global $ubillingConfig;
  96. $result = array();
  97. $tsFrom = strtotime($dateFrom);
  98. $tsTo = strtotime($dateTo);
  99. $delimiter = OphanimClassifier::DELIMITER;
  100. $source = OphanimClassifier::DATA_PATH . $direction . '_' . $ip;
  101. if (file_exists($source)) {
  102. if ($ubillingConfig->getAlterParam('SPEED_LOAD')) {
  103. $depthLimit = (($tsTo - $tsFrom) / 300) + 200;
  104. $depthLimit = round($depthLimit);
  105. $tailPath = $ubillingConfig->getAlterParam('TAIL_PATH');
  106. $command = $tailPath . ' -n ' . $depthLimit . ' ' . $source;
  107. $resultRaw = shell_exec($command);
  108. $resultRaw = explodeRows($resultRaw);
  109. if (!empty($resultRaw)) {
  110. foreach ($resultRaw as $io => $eachLine) {
  111. if (!empty($eachLine)) {
  112. $eachLine = explode($delimiter, $eachLine);
  113. if ($eachLine[0] >= $tsFrom and $eachLine[0] <= $tsTo) {
  114. $result[] = $eachLine;
  115. }
  116. }
  117. }
  118. }
  119. } else {
  120. $handle = fopen($source, 'r');
  121. while (!feof($handle)) {
  122. $buffer = fgets($handle, 4096);
  123. if (!empty($buffer)) {
  124. $eachLine = explode($delimiter, $buffer);
  125. if ($eachLine[0] >= $tsFrom and $eachLine[0] <= $tsTo) {
  126. $result[] = $eachLine;
  127. }
  128. }
  129. }
  130. fclose($handle);
  131. }
  132. }
  133. return ($result);
  134. }
  135. /**
  136. * Parses raw traffic data per line and returns it prepared for charting as datetime=>speedsArr
  137. *
  138. * @param array $rawData
  139. * @param bool $allocTimeline
  140. *
  141. * @return array
  142. */
  143. protected function parseSpeedData($rawData, $allocTimeline = false) {
  144. $result = array();
  145. global $ubillingConfig;
  146. $validationFlag = $ubillingConfig->getAlterParam('VALIDATE_COUNTERS');
  147. $validationFlag = ($validationFlag) ? true : false;
  148. if ($allocTimeline) {
  149. $result = allocDayTimeline();
  150. }
  151. if (!empty($rawData)) {
  152. $dataSize = sizeof($rawData);
  153. foreach ($rawData as $io => $eachLine) {
  154. $xAxis = ($dataSize < 287) ? date("H:i", $eachLine[0]) : date("d/m/Y H:i", $eachLine[0]);
  155. $tmpResult = array();
  156. foreach ($eachLine as $lnIdx => $lineData) {
  157. if ($lnIdx > 0) {
  158. $tmpResult[] = $this->bytesToSpeed($lineData, $validationFlag);
  159. }
  160. }
  161. $result[$xAxis] = $tmpResult;
  162. }
  163. }
  164. return ($result);
  165. }
  166. /**
  167. * Renders PNG chart for some IP
  168. *
  169. * @param string $ip
  170. * @param string $direction
  171. * @param string $dateFrom
  172. * @param string $dateTo
  173. * @param string $width
  174. * @param string $height
  175. * @param string $titleAppend
  176. *
  177. * @return void
  178. */
  179. public function renderGraph($ip, $direction, $dateFrom, $dateTo, $width = '', $height = '', $titleAppend = '') {
  180. $chartTitle = $ip;
  181. if ($direction == 'R') {
  182. $chartTitle = $ip . ' ' . __('Download');
  183. }
  184. if ($direction == 'S') {
  185. $chartTitle = $ip . ' ' . __('Upload');
  186. }
  187. if ($titleAppend) {
  188. $chartTitle .= $titleAppend;
  189. }
  190. $chartWidth = ($width) ? $width : 1540;
  191. $chartHeight = ($height) ? $height : 400;
  192. $chartMancer = new ChartMancer();
  193. $classifier = new OphanimClassifier();
  194. $legend = $classifier->getBaseStruct();
  195. $chartMancer->setImageWidth($chartWidth);
  196. $chartMancer->setImageHeight($chartHeight);
  197. $chartMancer->setPalette($this->palette);
  198. $chartMancer->setOverrideColors($this->colorOverrides);
  199. $chartMancer->setDebug($this->debug);
  200. $chartMancer->setChartLegend($legend);
  201. $chartMancer->setChartYaxisName(__('Mbit/s'));
  202. $chartMancer->setDisplayPeakValue(true);
  203. $chartMancer->setChartTitle($chartTitle);
  204. $chartDataRaw = $this->getChartData($ip, $direction, $dateFrom, $dateTo);
  205. $speedData = $this->parseSpeedData($chartDataRaw, false);
  206. if (sizeof($speedData) >= 288) {
  207. $chartMancer->setXLabelLen(10);
  208. $chartMancer->setXLabelsCount(12);
  209. $chartMancer->setCutSuffix('');
  210. }
  211. $chartMancer->setDrawFirstColumn($this->accurateFlag);
  212. $chartMancer->renderChart($speedData);
  213. }
  214. }