StatusController.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin\Controllers\Server\Status;
  4. use PhpMyAdmin\DatabaseInterface;
  5. use PhpMyAdmin\ReplicationGui;
  6. use PhpMyAdmin\Response;
  7. use PhpMyAdmin\Server\Status\Data;
  8. use PhpMyAdmin\Template;
  9. use PhpMyAdmin\Url;
  10. use PhpMyAdmin\Util;
  11. use function implode;
  12. /**
  13. * Object the server status page: processes, connections and traffic.
  14. */
  15. class StatusController extends AbstractController
  16. {
  17. /** @var ReplicationGui */
  18. private $replicationGui;
  19. /** @var DatabaseInterface */
  20. private $dbi;
  21. /**
  22. * @param Response $response
  23. * @param Data $data
  24. * @param DatabaseInterface $dbi
  25. */
  26. public function __construct($response, Template $template, $data, ReplicationGui $replicationGui, $dbi)
  27. {
  28. parent::__construct($response, $template, $data);
  29. $this->replicationGui = $replicationGui;
  30. $this->dbi = $dbi;
  31. }
  32. public function index(): void
  33. {
  34. global $err_url;
  35. $err_url = Url::getFromRoute('/');
  36. if ($this->dbi->isSuperUser()) {
  37. $this->dbi->selectDb('mysql');
  38. }
  39. $replicationInfo = $this->data->getReplicationInfo();
  40. $primaryInfo = $replicationInfo->getPrimaryInfo();
  41. $replicaInfo = $replicationInfo->getReplicaInfo();
  42. $traffic = [];
  43. $connections = [];
  44. $replication = '';
  45. if ($this->data->dataLoaded) {
  46. // In some case the data was reported not to exist, check it for all keys
  47. if (isset($this->data->status['Bytes_received'], $this->data->status['Bytes_sent'])) {
  48. $networkTraffic = implode(
  49. ' ',
  50. Util::formatByteDown(
  51. $this->data->status['Bytes_received'] + $this->data->status['Bytes_sent'],
  52. 3,
  53. 1
  54. )
  55. );
  56. }
  57. if (isset($this->data->status['Uptime'])) {
  58. $uptime = Util::timespanFormat($this->data->status['Uptime']);
  59. }
  60. $startTime = Util::localisedDate($this->getStartTime());
  61. $traffic = $this->getTrafficInfo();
  62. $connections = $this->getConnectionsInfo();
  63. if ($primaryInfo['status']) {
  64. $replication .= $this->replicationGui->getHtmlForReplicationStatusTable('master');
  65. }
  66. if ($replicaInfo['status']) {
  67. $replication .= $this->replicationGui->getHtmlForReplicationStatusTable('slave');
  68. }
  69. }
  70. $this->render('server/status/status/index', [
  71. 'is_data_loaded' => $this->data->dataLoaded,
  72. 'network_traffic' => $networkTraffic ?? null,
  73. 'uptime' => $uptime ?? null,
  74. 'start_time' => $startTime ?? null,
  75. 'traffic' => $traffic,
  76. 'connections' => $connections,
  77. 'is_master' => $primaryInfo['status'],
  78. 'is_slave' => $replicaInfo['status'],
  79. 'replication' => $replication,
  80. ]);
  81. }
  82. private function getStartTime(): int
  83. {
  84. return (int) $this->dbi->fetchValue(
  85. 'SELECT UNIX_TIMESTAMP() - ' . $this->data->status['Uptime']
  86. );
  87. }
  88. /**
  89. * @return array
  90. */
  91. private function getTrafficInfo(): array
  92. {
  93. $hourFactor = 3600 / $this->data->status['Uptime'];
  94. return [
  95. [
  96. 'name' => __('Received'),
  97. 'number' => implode(
  98. ' ',
  99. Util::formatByteDown(
  100. $this->data->status['Bytes_received'],
  101. 3,
  102. 1
  103. )
  104. ),
  105. 'per_hour' => implode(
  106. ' ',
  107. Util::formatByteDown(
  108. $this->data->status['Bytes_received'] * $hourFactor,
  109. 3,
  110. 1
  111. )
  112. ),
  113. ],
  114. [
  115. 'name' => __('Sent'),
  116. 'number' => implode(
  117. ' ',
  118. Util::formatByteDown(
  119. $this->data->status['Bytes_sent'],
  120. 3,
  121. 1
  122. )
  123. ),
  124. 'per_hour' => implode(
  125. ' ',
  126. Util::formatByteDown(
  127. $this->data->status['Bytes_sent'] * $hourFactor,
  128. 3,
  129. 1
  130. )
  131. ),
  132. ],
  133. [
  134. 'name' => __('Total'),
  135. 'number' => implode(
  136. ' ',
  137. Util::formatByteDown(
  138. $this->data->status['Bytes_received'] + $this->data->status['Bytes_sent'],
  139. 3,
  140. 1
  141. )
  142. ),
  143. 'per_hour' => implode(
  144. ' ',
  145. Util::formatByteDown(
  146. ($this->data->status['Bytes_received'] + $this->data->status['Bytes_sent']) * $hourFactor,
  147. 3,
  148. 1
  149. )
  150. ),
  151. ],
  152. ];
  153. }
  154. /**
  155. * @return array
  156. */
  157. private function getConnectionsInfo(): array
  158. {
  159. $hourFactor = 3600 / $this->data->status['Uptime'];
  160. $failedAttemptsPercentage = '---';
  161. $abortedPercentage = '---';
  162. if ($this->data->status['Connections'] > 0) {
  163. $failedAttemptsPercentage = Util::formatNumber(
  164. $this->data->status['Aborted_connects'] * 100 / $this->data->status['Connections'],
  165. 0,
  166. 2,
  167. true
  168. ) . '%';
  169. $abortedPercentage = Util::formatNumber(
  170. $this->data->status['Aborted_clients'] * 100 / $this->data->status['Connections'],
  171. 0,
  172. 2,
  173. true
  174. ) . '%';
  175. }
  176. return [
  177. [
  178. 'name' => __('Max. concurrent connections'),
  179. 'number' => Util::formatNumber(
  180. $this->data->status['Max_used_connections'],
  181. 0
  182. ),
  183. 'per_hour' => '---',
  184. 'percentage' => '---',
  185. ],
  186. [
  187. 'name' => __('Failed attempts'),
  188. 'number' => Util::formatNumber(
  189. $this->data->status['Aborted_connects'],
  190. 4,
  191. 1,
  192. true
  193. ),
  194. 'per_hour' => Util::formatNumber(
  195. $this->data->status['Aborted_connects'] * $hourFactor,
  196. 4,
  197. 2,
  198. true
  199. ),
  200. 'percentage' => $failedAttemptsPercentage,
  201. ],
  202. [
  203. 'name' => __('Aborted'),
  204. 'number' => Util::formatNumber(
  205. $this->data->status['Aborted_clients'],
  206. 4,
  207. 1,
  208. true
  209. ),
  210. 'per_hour' => Util::formatNumber(
  211. $this->data->status['Aborted_clients'] * $hourFactor,
  212. 4,
  213. 2,
  214. true
  215. ),
  216. 'percentage' => $abortedPercentage,
  217. ],
  218. [
  219. 'name' => __('Total'),
  220. 'number' => Util::formatNumber(
  221. $this->data->status['Connections'],
  222. 4,
  223. 0
  224. ),
  225. 'per_hour' => Util::formatNumber(
  226. $this->data->status['Connections'] * $hourFactor,
  227. 4,
  228. 2
  229. ),
  230. 'percentage' => Util::formatNumber(100, 0, 2) . '%',
  231. ],
  232. ];
  233. }
  234. }