server_status_monitor.php 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Server status monitor feature
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. require_once 'libraries/common.inc.php';
  9. require_once 'libraries/server_common.inc.php';
  10. require_once 'libraries/ServerStatusData.class.php';
  11. if (PMA_DRIZZLE) {
  12. $server_master_status = false;
  13. $server_slave_status = false;
  14. } else {
  15. include_once 'libraries/replication.inc.php';
  16. include_once 'libraries/replication_gui.lib.php';
  17. }
  18. /**
  19. * Ajax request
  20. */
  21. if (isset($_REQUEST['ajax_request']) && $_REQUEST['ajax_request'] == true) {
  22. // Send with correct charset
  23. header('Content-Type: text/html; charset=UTF-8');
  24. // real-time charting data
  25. if (isset($_REQUEST['chart_data'])) {
  26. switch($_REQUEST['type']) {
  27. case 'chartgrid': // Data for the monitor
  28. $ret = json_decode($_REQUEST['requiredData'], true);
  29. $statusVars = array();
  30. $serverVars = array();
  31. $sysinfo = $cpuload = $memory = 0;
  32. $pName = '';
  33. /* Accumulate all required variables and data */
  34. // For each chart
  35. foreach ($ret as $chart_id => $chartNodes) {
  36. // For each data series
  37. foreach ($chartNodes as $node_id => $nodeDataPoints) {
  38. // For each data point in the series (usually just 1)
  39. foreach ($nodeDataPoints as $point_id => $dataPoint) {
  40. $pName = $dataPoint['name'];
  41. switch ($dataPoint['type']) {
  42. /* We only collect the status and server variables here to
  43. * read them all in one query,
  44. * and only afterwards assign them.
  45. * Also do some white list filtering on the names
  46. */
  47. case 'servervar':
  48. if (! preg_match('/[^a-zA-Z_]+/', $pName)) {
  49. $serverVars[] = $pName;
  50. }
  51. break;
  52. case 'statusvar':
  53. if (! preg_match('/[^a-zA-Z_]+/', $pName)) {
  54. $statusVars[] = $pName;
  55. }
  56. break;
  57. case 'proc':
  58. $result = PMA_DBI_query('SHOW PROCESSLIST');
  59. $ret[$chart_id][$node_id][$point_id]['value']
  60. = PMA_DBI_num_rows($result);
  61. break;
  62. case 'cpu':
  63. if (!$sysinfo) {
  64. include_once 'libraries/sysinfo.lib.php';
  65. $sysinfo = PMA_getSysInfo();
  66. }
  67. if (!$cpuload) {
  68. $cpuload = $sysinfo->loadavg();
  69. }
  70. if (PMA_getSysInfoOs() == 'Linux') {
  71. $ret[$chart_id][$node_id][$point_id]['idle']
  72. = $cpuload['idle'];
  73. $ret[$chart_id][$node_id][$point_id]['busy']
  74. = $cpuload['busy'];
  75. } else {
  76. $ret[$chart_id][$node_id][$point_id]['value']
  77. = $cpuload['loadavg'];
  78. }
  79. break;
  80. case 'memory':
  81. if (!$sysinfo) {
  82. include_once 'libraries/sysinfo.lib.php';
  83. $sysinfo = PMA_getSysInfo();
  84. }
  85. if (!$memory) {
  86. $memory = $sysinfo->memory();
  87. }
  88. $ret[$chart_id][$node_id][$point_id]['value']
  89. = $memory[$pName];
  90. break;
  91. } /* switch */
  92. } /* foreach */
  93. } /* foreach */
  94. } /* foreach */
  95. // Retrieve all required status variables
  96. if (count($statusVars)) {
  97. $statusVarValues = PMA_DBI_fetch_result(
  98. "SHOW GLOBAL STATUS WHERE Variable_name='"
  99. . implode("' OR Variable_name='", $statusVars) . "'",
  100. 0,
  101. 1
  102. );
  103. } else {
  104. $statusVarValues = array();
  105. }
  106. // Retrieve all required server variables
  107. if (count($serverVars)) {
  108. $serverVarValues = PMA_DBI_fetch_result(
  109. "SHOW GLOBAL VARIABLES WHERE Variable_name='"
  110. . implode("' OR Variable_name='", $serverVars) . "'",
  111. 0,
  112. 1
  113. );
  114. } else {
  115. $serverVarValues = array();
  116. }
  117. // ...and now assign them
  118. foreach ($ret as $chart_id => $chartNodes) {
  119. foreach ($chartNodes as $node_id => $nodeDataPoints) {
  120. foreach ($nodeDataPoints as $point_id => $dataPoint) {
  121. switch($dataPoint['type']) {
  122. case 'statusvar':
  123. $ret[$chart_id][$node_id][$point_id]['value']
  124. = $statusVarValues[$dataPoint['name']];
  125. break;
  126. case 'servervar':
  127. $ret[$chart_id][$node_id][$point_id]['value']
  128. = $serverVarValues[$dataPoint['name']];
  129. break;
  130. }
  131. }
  132. }
  133. }
  134. $ret['x'] = microtime(true) * 1000;
  135. PMA_Response::getInstance()->addJSON('message', $ret);
  136. exit;
  137. }
  138. }
  139. if (isset($_REQUEST['log_data'])) {
  140. if (PMA_MYSQL_INT_VERSION < 50106) {
  141. // Table logging is only available since 5.1.6
  142. exit('""');
  143. }
  144. $start = intval($_REQUEST['time_start']);
  145. $end = intval($_REQUEST['time_end']);
  146. if ($_REQUEST['type'] == 'slow') {
  147. $q = 'SELECT start_time, user_host, ';
  148. $q .= 'Sec_to_Time(Sum(Time_to_Sec(query_time))) as query_time, ';
  149. $q .= 'Sec_to_Time(Sum(Time_to_Sec(lock_time))) as lock_time, ';
  150. $q .= 'SUM(rows_sent) AS rows_sent, ';
  151. $q .= 'SUM(rows_examined) AS rows_examined, db, sql_text, ';
  152. $q .= 'COUNT(sql_text) AS \'#\' ';
  153. $q .= 'FROM `mysql`.`slow_log` ';
  154. $q .= 'WHERE start_time > FROM_UNIXTIME(' . $start . ') ';
  155. $q .= 'AND start_time < FROM_UNIXTIME(' . $end . ') GROUP BY sql_text';
  156. $result = PMA_DBI_try_query($q);
  157. $return = array('rows' => array(), 'sum' => array());
  158. $type = '';
  159. while ($row = PMA_DBI_fetch_assoc($result)) {
  160. $type = strtolower(
  161. substr($row['sql_text'], 0, strpos($row['sql_text'], ' '))
  162. );
  163. switch($type) {
  164. case 'insert':
  165. case 'update':
  166. //Cut off big inserts and updates, but append byte count instead
  167. if (strlen($row['sql_text']) > 220) {
  168. $implode_sql_text = implode(
  169. ' ',
  170. PMA_Util::formatByteDown(
  171. strlen($row['sql_text']), 2, 2
  172. )
  173. );
  174. $row['sql_text'] = substr($row['sql_text'], 0, 200)
  175. . '... [' . $implode_sql_text . ']';
  176. }
  177. break;
  178. default:
  179. break;
  180. }
  181. if (! isset($return['sum'][$type])) {
  182. $return['sum'][$type] = 0;
  183. }
  184. $return['sum'][$type] += $row['#'];
  185. $return['rows'][] = $row;
  186. }
  187. $return['sum']['TOTAL'] = array_sum($return['sum']);
  188. $return['numRows'] = count($return['rows']);
  189. PMA_DBI_free_result($result);
  190. PMA_Response::getInstance()->addJSON('message', $return);
  191. exit;
  192. }
  193. if ($_REQUEST['type'] == 'general') {
  194. $limitTypes = '';
  195. if (isset($_REQUEST['limitTypes']) && $_REQUEST['limitTypes']) {
  196. $limitTypes
  197. = 'AND argument REGEXP \'^(INSERT|SELECT|UPDATE|DELETE)\' ';
  198. }
  199. $q = 'SELECT TIME(event_time) as event_time, user_host, thread_id, ';
  200. $q .= 'server_id, argument, count(argument) as \'#\' ';
  201. $q .= 'FROM `mysql`.`general_log` ';
  202. $q .= 'WHERE command_type=\'Query\' ';
  203. $q .= 'AND event_time > FROM_UNIXTIME(' . $start . ') ';
  204. $q .= 'AND event_time < FROM_UNIXTIME(' . $end . ') ';
  205. $q .= $limitTypes . 'GROUP by argument'; // HAVING count > 1';
  206. $result = PMA_DBI_try_query($q);
  207. $return = array('rows' => array(), 'sum' => array());
  208. $type = '';
  209. $insertTables = array();
  210. $insertTablesFirst = -1;
  211. $i = 0;
  212. $removeVars = isset($_REQUEST['removeVariables'])
  213. && $_REQUEST['removeVariables'];
  214. while ($row = PMA_DBI_fetch_assoc($result)) {
  215. preg_match('/^(\w+)\s/', $row['argument'], $match);
  216. $type = strtolower($match[1]);
  217. if (! isset($return['sum'][$type])) {
  218. $return['sum'][$type] = 0;
  219. }
  220. $return['sum'][$type] += $row['#'];
  221. switch($type) {
  222. case 'insert':
  223. // Group inserts if selected
  224. if ($removeVars
  225. && preg_match(
  226. '/^INSERT INTO (`|\'|"|)([^\s\\1]+)\\1/i',
  227. $row['argument'], $matches
  228. )
  229. ) {
  230. $insertTables[$matches[2]]++;
  231. if ($insertTables[$matches[2]] > 1) {
  232. $return['rows'][$insertTablesFirst]['#']
  233. = $insertTables[$matches[2]];
  234. // Add a ... to the end of this query to indicate that
  235. // there's been other queries
  236. $temp = $return['rows'][$insertTablesFirst]['argument'];
  237. if ($temp[strlen($temp) - 1] != '.') {
  238. $return['rows'][$insertTablesFirst]['argument']
  239. .= '<br/>...';
  240. }
  241. // Group this value, thus do not add to the result list
  242. continue 2;
  243. } else {
  244. $insertTablesFirst = $i;
  245. $insertTables[$matches[2]] += $row['#'] - 1;
  246. }
  247. }
  248. // No break here
  249. case 'update':
  250. // Cut off big inserts and updates,
  251. // but append byte count therefor
  252. if (strlen($row['argument']) > 220) {
  253. $row['argument'] = substr($row['argument'], 0, 200)
  254. . '... ['
  255. . implode(
  256. ' ',
  257. PMA_Util::formatByteDown(
  258. strlen($row['argument']),
  259. 2,
  260. 2
  261. )
  262. )
  263. . ']';
  264. }
  265. break;
  266. default:
  267. break;
  268. }
  269. $return['rows'][] = $row;
  270. $i++;
  271. }
  272. $return['sum']['TOTAL'] = array_sum($return['sum']);
  273. $return['numRows'] = count($return['rows']);
  274. PMA_DBI_free_result($result);
  275. PMA_Response::getInstance()->addJSON('message', $return);
  276. exit;
  277. }
  278. }
  279. if (isset($_REQUEST['logging_vars'])) {
  280. if (isset($_REQUEST['varName']) && isset($_REQUEST['varValue'])) {
  281. $value = PMA_Util::sqlAddSlashes($_REQUEST['varValue']);
  282. if (! is_numeric($value)) {
  283. $value="'" . $value . "'";
  284. }
  285. if (! preg_match("/[^a-zA-Z0-9_]+/", $_REQUEST['varName'])) {
  286. PMA_DBI_query(
  287. 'SET GLOBAL ' . $_REQUEST['varName'] . ' = ' . $value
  288. );
  289. }
  290. }
  291. $loggingVars = PMA_DBI_fetch_result(
  292. 'SHOW GLOBAL VARIABLES WHERE Variable_name IN'
  293. . ' ("general_log","slow_query_log","long_query_time","log_output")',
  294. 0,
  295. 1
  296. );
  297. PMA_Response::getInstance()->addJSON('message', $loggingVars);
  298. exit;
  299. }
  300. if (isset($_REQUEST['query_analyzer'])) {
  301. $return = array();
  302. if (strlen($_REQUEST['database'])) {
  303. PMA_DBI_select_db($_REQUEST['database']);
  304. }
  305. if ($profiling = PMA_Util::profilingSupported()) {
  306. PMA_DBI_query('SET PROFILING=1;');
  307. }
  308. // Do not cache query
  309. $query = preg_replace(
  310. '/^(\s*SELECT)/i',
  311. '\\1 SQL_NO_CACHE',
  312. $_REQUEST['query']
  313. );
  314. $result = PMA_DBI_try_query($query);
  315. $return['affectedRows'] = $GLOBALS['cached_affected_rows'];
  316. $result = PMA_DBI_try_query('EXPLAIN ' . $query);
  317. while ($row = PMA_DBI_fetch_assoc($result)) {
  318. $return['explain'][] = $row;
  319. }
  320. // In case an error happened
  321. $return['error'] = PMA_DBI_getError();
  322. PMA_DBI_free_result($result);
  323. if ($profiling) {
  324. $return['profiling'] = array();
  325. $result = PMA_DBI_try_query(
  326. 'SELECT seq,state,duration FROM INFORMATION_SCHEMA.PROFILING'
  327. . ' WHERE QUERY_ID=1 ORDER BY seq'
  328. );
  329. while ($row = PMA_DBI_fetch_assoc($result)) {
  330. $return['profiling'][]= $row;
  331. }
  332. PMA_DBI_free_result($result);
  333. }
  334. PMA_Response::getInstance()->addJSON('message', $return);
  335. exit;
  336. }
  337. }
  338. /**
  339. * JS Includes
  340. */
  341. $header = $response->getHeader();
  342. $scripts = $header->getScripts();
  343. $scripts->addFile('jquery/jquery.tablesorter.js');
  344. $scripts->addFile('jquery/jquery.json-2.4.js');
  345. $scripts->addFile('jquery/jquery.sortableTable.js');
  346. $scripts->addFile('jquery/jquery-ui-timepicker-addon.js');
  347. /* < IE 9 doesn't support canvas natively */
  348. if (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 9) {
  349. $scripts->addFile('jqplot/excanvas.js');
  350. }
  351. $scripts->addFile('canvg/canvg.js');
  352. // for charting
  353. $scripts->addFile('jqplot/jquery.jqplot.js');
  354. $scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js');
  355. $scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js');
  356. $scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js');
  357. $scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js');
  358. $scripts->addFile('jqplot/plugins/jqplot.highlighter.js');
  359. $scripts->addFile('jqplot/plugins/jqplot.cursor.js');
  360. $scripts->addFile('jqplot/plugins/jqplot.byteFormatter.js');
  361. $scripts->addFile('server_status_monitor.js');
  362. $scripts->addFile('server_status_sorter.js');
  363. /**
  364. * start output
  365. */
  366. $ServerStatusData = new PMA_ServerStatusData();
  367. /**
  368. * Define some data needed on the client side
  369. */
  370. $input = '<input type="hidden" name="%s" value="%s" />';
  371. $form = '<form id="js_data" class="hide">';
  372. $form .= sprintf($input, 'server_time', microtime(true) * 1000);
  373. $form .= sprintf($input, 'server_os', PHP_OS);
  374. $form .= sprintf($input, 'is_superuser', PMA_isSuperuser());
  375. $form .= sprintf($input, 'server_db_isLocal', $ServerStatusData->db_isLocal);
  376. $form .= '</form>';
  377. /**
  378. * Define some links used on client side
  379. */
  380. $links = '<div id="profiling_docu" class="hide">';
  381. $links .= PMA_Util::showMySQLDocu('general-thread-states', 'general-thread-states');
  382. $links .= '</div>';
  383. $links .= '<div id="explain_docu" class="hide">';
  384. $links .= PMA_Util::showMySQLDocu('explain-output', 'explain-output');
  385. $links .= '</div>';
  386. /**
  387. * Output
  388. */
  389. $response->addHTML('<div>');
  390. $response->addHTML($ServerStatusData->getMenuHtml());
  391. $response->addHTML(getPrintMonitorHtml($ServerStatusData));
  392. $response->addHTML($form);
  393. $response->addHTML($links);
  394. $response->addHTML('</div>');
  395. exit;
  396. /**
  397. * Prints html with monitor
  398. *
  399. * @param object $ServerStatusData An instance of the PMA_ServerStatusData class
  400. *
  401. * @return string
  402. */
  403. function getPrintMonitorHtml($ServerStatusData)
  404. {
  405. $retval = '<div class="tabLinks">';
  406. $retval .= '<a href="#pauseCharts">';
  407. $retval .= PMA_Util::getImage('play.png') . __('Start Monitor');
  408. $retval .= '</a>';
  409. $retval .= '<a href="#settingsPopup" class="popupLink">';
  410. $retval .= PMA_Util::getImage('s_cog.png') . __('Settings');
  411. $retval .= '</a>';
  412. if (! PMA_DRIZZLE) {
  413. $retval .= '<a href="#monitorInstructionsDialog">';
  414. $retval .= PMA_Util::getImage('b_help.png') . __('Instructions/Setup');
  415. }
  416. $retval .= '<a href="#endChartEditMode" style="display:none;">';
  417. $retval .= PMA_Util::getImage('s_okay.png');
  418. $retval .= __('Done dragging (rearranging) charts');
  419. $retval .= '</a>';
  420. $retval .= '</div>';
  421. $retval .= '<div class="popupContent settingsPopup">';
  422. $retval .= '<a href="#addNewChart">';
  423. $retval .= PMA_Util::getImage('b_chart.png') . __('Add chart');
  424. $retval .= '</a>';
  425. $retval .= '<a href="#rearrangeCharts">';
  426. $retval .= PMA_Util::getImage('b_tblops.png') . __('Enable charts dragging');
  427. $retval .= '</a>';
  428. $retval .= '<div class="clearfloat paddingtop"></div>';
  429. $retval .= '<div class="floatleft">';
  430. $retval .= __('Refresh rate') . '<br />';
  431. $retval .= PMA_getRefreshList(
  432. 'gridChartRefresh',
  433. 5,
  434. Array(2, 3, 4, 5, 10, 20, 40, 60, 120, 300, 600, 1200)
  435. );
  436. $retval .= '<br />';
  437. $retval .= '</div>';
  438. $retval .= '<div class="floatleft">';
  439. $retval .= __('Chart columns');
  440. $retval .= '<br />';
  441. $retval .= '<select name="chartColumns">';
  442. $retval .= '<option>1</option>';
  443. $retval .= '<option>2</option>';
  444. $retval .= '<option>3</option>';
  445. $retval .= '<option>4</option>';
  446. $retval .= '<option>5</option>';
  447. $retval .= '<option>6</option>';
  448. $retval .= '<option>7</option>';
  449. $retval .= '<option>8</option>';
  450. $retval .= '<option>9</option>';
  451. $retval .= '<option>10</option>';
  452. $retval .= '</select>';
  453. $retval .= '</div>';
  454. $retval .= '<div class="clearfloat paddingtop">';
  455. $retval .= '<b>' . __('Chart arrangement') . '</b> ';
  456. $retval .= PMA_Util::showHint(
  457. __(
  458. 'The arrangement of the charts is stored to the browsers local storage. '
  459. . 'You may want to export it if you have a complicated set up.'
  460. )
  461. );
  462. $retval .= '<br/>';
  463. $retval .= '<a class="ajax" href="#importMonitorConfig">';
  464. $retval .= __('Import');
  465. $retval .= '</a>';
  466. $retval .= '&nbsp;&nbsp;';
  467. $retval .= '<a class="disableAjax" href="#exportMonitorConfig">';
  468. $retval .= __('Export');
  469. $retval .= '</a>';
  470. $retval .= '&nbsp;&nbsp;';
  471. $retval .= '<a href="#clearMonitorConfig">';
  472. $retval .= __('Reset to default');
  473. $retval .= '</a>';
  474. $retval .= '</div>';
  475. $retval .= '</div>';
  476. $retval .= '<div id="monitorInstructionsDialog" title="';
  477. $retval .= __('Monitor Instructions') . '" style="display:none;">';
  478. $retval .= __(
  479. 'The phpMyAdmin Monitor can assist you in optimizing the server'
  480. . ' configuration and track down time intensive queries. For the latter you'
  481. . ' will need to set log_output to \'TABLE\' and have either the'
  482. . ' slow_query_log or general_log enabled. Note however, that the'
  483. . ' general_log produces a lot of data and increases server load'
  484. . ' by up to 15%'
  485. );
  486. if (PMA_MYSQL_INT_VERSION < 50106) {
  487. $retval .= '<p>';
  488. $retval .= PMA_Util::getImage('s_attention.png');
  489. $retval .= __(
  490. 'Unfortunately your Database server does not support logging to table,'
  491. . ' which is a requirement for analyzing the database logs with'
  492. . ' phpMyAdmin. Logging to table is supported by MySQL 5.1.6 and'
  493. . ' onwards. You may still use the server charting features however.'
  494. );
  495. $retval .= '</p>';
  496. } else {
  497. $retval .= '<p></p>';
  498. $retval .= '<img class="ajaxIcon" src="';
  499. $retval .= $GLOBALS['pmaThemeImage'] . 'ajax_clock_small.gif"';
  500. $retval .= ' alt="' . __('Loading') . '" />';
  501. $retval .= '<div class="ajaxContent"></div>';
  502. $retval .= '<div class="monitorUse" style="display:none;">';
  503. $retval .= '<p></p>';
  504. $retval .= '<strong>';
  505. $retval .= __('Using the monitor:');
  506. $retval .= '</strong><p>';
  507. $retval .= __(
  508. 'Your browser will refresh all displayed charts in a regular interval.'
  509. . ' You may add charts and change the refresh rate under \'Settings\','
  510. . ' or remove any chart using the cog icon on each respective chart.'
  511. );
  512. $retval .= '</p><p>';
  513. $retval .= __(
  514. 'To display queries from the logs, select the relevant time span on any'
  515. . ' chart by holding down the left mouse button and panning over the'
  516. . ' chart. Once confirmed, this will load a table of grouped queries,'
  517. . ' there you may click on any occuring SELECT statements to further'
  518. . ' analyze them.'
  519. );
  520. $retval .= '</p>';
  521. $retval .= '<p>';
  522. $retval .= PMA_Util::getImage('s_attention.png');
  523. $retval .= '<strong>';
  524. $retval .= __('Please note:');
  525. $retval .= '</strong><br />';
  526. $retval .= __(
  527. 'Enabling the general_log may increase the server load by'
  528. . ' 5-15%. Also be aware that generating statistics from the logs is a'
  529. . ' load intensive task, so it is advisable to select only a small time'
  530. . ' span and to disable the general_log and empty its table once'
  531. . ' monitoring is not required any more.'
  532. );
  533. $retval .= '</p>';
  534. $retval .= '</div>';
  535. }
  536. $retval .= '</div>';
  537. $retval .= '<div id="addChartDialog" title="' . __('Add chart') . '" style="display:none;">';
  538. $retval .= '<div id="tabGridVariables">';
  539. $retval .= '<p><input type="text" name="chartTitle" value="' . __('Chart Title') . '" /></p>';
  540. $retval .= '<input type="radio" name="chartType" value="preset" id="chartPreset" />';
  541. $retval .= '<label for="chartPreset">' . __('Preset chart') . '</label>';
  542. $retval .= '<select name="presetCharts"></select><br/>';
  543. $retval .= '<input type="radio" name="chartType" value="variable" id="chartStatusVar" checked="checked" />';
  544. $retval .= '<label for="chartStatusVar">';
  545. $retval .= __('Status variable(s)');
  546. $retval .= '</label><br/>';
  547. $retval .= '<div id="chartVariableSettings">';
  548. $retval .= '<label for="chartSeries">' . __('Select series:') . '</label><br />';
  549. $retval .= '<select id="chartSeries" name="varChartList" size="1">';
  550. $retval .= '<option>' . __('Commonly monitored') . '</option>';
  551. $retval .= '<option>Processes</option>';
  552. $retval .= '<option>Questions</option>';
  553. $retval .= '<option>Connections</option>';
  554. $retval .= '<option>Bytes_sent</option>';
  555. $retval .= '<option>Bytes_received</option>';
  556. $retval .= '<option>Threads_connected</option>';
  557. $retval .= '<option>Created_tmp_disk_tables</option>';
  558. $retval .= '<option>Handler_read_first</option>';
  559. $retval .= '<option>Innodb_buffer_pool_wait_free</option>';
  560. $retval .= '<option>Key_reads</option>';
  561. $retval .= '<option>Open_tables</option>';
  562. $retval .= '<option>Select_full_join</option>';
  563. $retval .= '<option>Slow_queries</option>';
  564. $retval .= '</select><br />';
  565. $retval .= '<label for="variableInput">';
  566. $retval .= __('or type variable name:');
  567. $retval .= ' </label>';
  568. $retval .= '<input type="text" name="variableInput" id="variableInput" />';
  569. $retval .= '<p></p>';
  570. $retval .= '<input type="checkbox" name="differentialValue"';
  571. $retval .= ' id="differentialValue" value="differential" checked="checked" />';
  572. $retval .= '<label for="differentialValue">';
  573. $retval .= __('Display as differential value');
  574. $retval .= '</label><br />';
  575. $retval .= '<input type="checkbox" id="useDivisor" name="useDivisor" value="1" />';
  576. $retval .= '<label for="useDivisor">' . __('Apply a divisor') . '</label>';
  577. $retval .= '<span class="divisorInput" style="display:none;">';
  578. $retval .= '<input type="text" name="valueDivisor" size="4" value="1" />';
  579. $retval .= '(<a href="#kibDivisor">' . __('KiB') . '</a>, ';
  580. $retval .= '<a href="#mibDivisor">' . __('MiB') . '</a>)';
  581. $retval .= '</span><br />';
  582. $retval .= '<input type="checkbox" id="useUnit" name="useUnit" value="1" />';
  583. $retval .= '<label for="useUnit">';
  584. $retval .= __('Append unit to data values');
  585. $retval .= '</label>';
  586. $retval .= '<span class="unitInput" style="display:none;">';
  587. $retval .= '<input type="text" name="valueUnit" size="4" value="" />';
  588. $retval .= '</span>';
  589. $retval .= '<p>';
  590. $retval .= '<a href="#submitAddSeries"><b>' . __('Add this series') . '</b></a>';
  591. $retval .= '<span id="clearSeriesLink" style="display:none;">';
  592. $retval .= ' | <a href="#submitClearSeries">' . __('Clear series') . '</a>';
  593. $retval .= '</span>';
  594. $retval .= '</p>';
  595. $retval .= __('Series in Chart:');
  596. $retval .= '<br/>';
  597. $retval .= '<span id="seriesPreview">';
  598. $retval .= '<i>' . __('None') . '</i>';
  599. $retval .= '</span>';
  600. $retval .= '</div>';
  601. $retval .= '</div>';
  602. $retval .= '</div>';
  603. if (! PMA_DRIZZLE) {
  604. $retval .= '<div id="logAnalyseDialog" title="';
  605. $retval .= __('Log statistics') . '" style="display:none;">';
  606. $retval .= '<p>' . __('Selected time range:');
  607. $retval .= '<input type="text" name="dateStart" class="datetimefield" value="" /> - ';
  608. $retval .= '<input type="text" name="dateEnd" class="datetimefield" value="" />';
  609. $retval .= '</p>';
  610. $retval .= '<input type="checkbox" id="limitTypes" value="1" checked="checked" />';
  611. $retval .= '<label for="limitTypes">';
  612. $retval .= __('Only retrieve SELECT,INSERT,UPDATE and DELETE Statements');
  613. $retval .= '</label>';
  614. $retval .= '<br/>';
  615. $retval .= '<input type="checkbox" id="removeVariables" value="1" checked="checked" />';
  616. $retval .= '<label for="removeVariables">';
  617. $retval .= __('Remove variable data in INSERT statements for better grouping');
  618. $retval .= '</label>';
  619. $retval .= '<p>';
  620. $retval .= __('Choose from which log you want the statistics to be generated from.');
  621. $retval .= '</p>';
  622. $retval .= '<p>';
  623. $retval .= __('Results are grouped by query text.');
  624. $retval .= '</p>';
  625. $retval .= '</div>';
  626. $retval .= '<div id="queryAnalyzerDialog" title="';
  627. $retval .= __('Query analyzer') . '" style="display:none;">';
  628. $retval .= '<textarea id="sqlquery"> </textarea>';
  629. $retval .= '<p></p>';
  630. $retval .= '<div class="placeHolder"></div>';
  631. $retval .= '</div>';
  632. }
  633. $retval .= '<table class="clearfloat" id="chartGrid"></table>';
  634. $retval .= '<div id="logTable">';
  635. $retval .= '<br/>';
  636. $retval .= '</div>';
  637. $retval .= '<script type="text/javascript">';
  638. $retval .= 'variableNames = [ ';
  639. $i=0;
  640. foreach ($ServerStatusData->status as $name=>$value) {
  641. if (is_numeric($value)) {
  642. if ($i++ > 0) {
  643. $retval .= ", ";
  644. }
  645. $retval .= "'" . $name . "'";
  646. }
  647. }
  648. $retval .= '];';
  649. $retval .= '</script>';
  650. return $retval;
  651. }
  652. /**
  653. * Builds a <select> list for refresh rates
  654. *
  655. * @param string $name Name of select
  656. * @param int $defaultRate Currently chosen rate
  657. * @param array $refreshRates List of refresh rates
  658. *
  659. * @return string
  660. */
  661. function PMA_getRefreshList($name,
  662. $defaultRate = 5,
  663. $refreshRates = Array(1, 2, 5, 10, 20, 40, 60, 120, 300, 600)
  664. ) {
  665. $return = '<select name="' . $name . '" id="id_' . $name
  666. . '" class="refreshRate">';
  667. foreach ($refreshRates as $rate) {
  668. $selected = ($rate == $defaultRate)?' selected="selected"':'';
  669. $return .= '<option value="' . $rate . '"' . $selected . '>';
  670. if ($rate < 60) {
  671. $return .= sprintf(_ngettext('%d second', '%d seconds', $rate), $rate);
  672. } else {
  673. $rate = $rate / 60;
  674. $return .= sprintf(_ngettext('%d minute', '%d minutes', $rate), $rate);
  675. }
  676. $return .= '</option>';
  677. }
  678. $return .= '</select>';
  679. return $return;
  680. }
  681. ?>