replay_query_log.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. // Copyright (C) 2010-2012 Combodo SARL
  3. //
  4. // This file is part of iTop.
  5. //
  6. // iTop is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU Affero General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // iTop is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU Affero General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU Affero General Public License
  17. // along with iTop. If not, see <http://www.gnu.org/licenses/>
  18. /**
  19. * Replay the query log made when log_queries = 1
  20. *
  21. * @copyright Copyright (C) 2010-2012 Combodo SARL
  22. * @license http://opensource.org/licenses/AGPL-3.0
  23. */
  24. function LogResult($sString)
  25. {
  26. file_put_contents(APPROOT.'data/queries.results.log', "\n".$sString, FILE_APPEND);
  27. }
  28. function LogBenchmarkCSV()
  29. {
  30. $aValues = array();
  31. foreach (func_get_args() as $arg)
  32. {
  33. if (is_string($arg))
  34. {
  35. $aValues[] = '"'.str_replace('"', '\\"', $arg).'"';
  36. }
  37. else
  38. {
  39. $aValues[] = (string) $arg;
  40. }
  41. }
  42. $sLine = implode(';', $aValues); // the preferred for MS Excel
  43. file_put_contents(APPROOT.'data/queries.benchmark.csv', "\n".$sLine, FILE_APPEND);
  44. }
  45. /////////////////////////////////////////////////////////////////////////////
  46. //
  47. // Main program
  48. //
  49. /////////////////////////////////////////////////////////////////////////////
  50. require_once('../approot.inc.php');
  51. require_once(APPROOT.'/application/application.inc.php');
  52. require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
  53. require_once(APPROOT.'/application/startup.inc.php');
  54. $operation = utils::ReadParam('operation', '');
  55. require_once(APPROOT.'/application/loginwebpage.class.inc.php');
  56. LoginWebPage::DoLogin(); // Check user rights and prompt if needed
  57. $oP = new WebPage('Replay queries.log');
  58. ini_set('memory_limit', '512M');
  59. require_once(APPROOT.'/data/queries.log');
  60. $iCount = count($aQueriesLog);
  61. $oP->p("Nombre de requêtes: ".$iCount);
  62. $sOperation = utils::ReadParam('operation', '');
  63. switch ($sOperation)
  64. {
  65. case '':
  66. default:
  67. $oP->add("<ol>\n");
  68. foreach ($aQueriesLog as $sQueryId => $aOqlData)
  69. {
  70. $sOql = $aOqlData['oql'];
  71. $sOqlHtml = htmlentities($sOql, ENT_QUOTES, 'UTF-8');
  72. $oP->add("<li>$sOqlHtml</li>\n");
  73. }
  74. $oP->add("</ol>\n");
  75. $oP->add("<form action=\"?operation=benchmark\" method=\"post\">\n");
  76. $oP->add("<input type=\"submit\" value=\"Benchmark!\">\n");
  77. $oP->add("</form>\n");
  78. break;
  79. case 'benchmark':
  80. // Reset the log contents
  81. file_put_contents(APPROOT.'data/queries.results.log', date('Y-m-d H:i:s')."\n");
  82. file_put_contents(APPROOT.'data/queries.benchmark.csv', '');
  83. LogBenchmarkCSV('oql', 'type', 'properties', 'make duration', 'tables', 'query length', 'exec duration', 'rows');
  84. foreach ($aQueriesLog as $sQueryId => $aOqlData)
  85. {
  86. $sOql = $aOqlData['oql'];
  87. $sOqlHtml = htmlentities($sOql, ENT_QUOTES, 'UTF-8');
  88. $aQueryData = unserialize($aOqlData['data']);
  89. $oFilter = $aQueryData['filter'];
  90. $aArgs = $aQueryData['args'];
  91. if ($aQueryData['type'] == 'select')
  92. {
  93. $aOrderBy = $aQueryData['order_by'];
  94. $aAttToLoad = $aQueryData['att_to_load'];
  95. $aExtendedDataSpec = $aQueryData['extended_data_spec'];
  96. $iLimitCount = $aQueryData['limit_count'];
  97. $iLimitStart = $aQueryData['limit_start'];
  98. $bGetCount = $aQueryData['is_count'];
  99. if ($bGetCount)
  100. {
  101. $sQueryType = 'COUNT';
  102. $sQueryDesc = '';
  103. }
  104. else
  105. {
  106. $sQueryType = 'LIST';
  107. $sQueryDesc = "limit count: $iLimitCount";
  108. $sQueryDesc .= "; limit start: $iLimitStart";
  109. if (count($aOrderBy) > 0)
  110. {
  111. $sQueryDesc .= "; order by: ".implode(',', array_keys($aOrderBy));
  112. }
  113. if (is_array($aAttToLoad))
  114. {
  115. $sQueryDesc .= "; attributes: ".implode(',', array_keys($aAttToLoad));
  116. }
  117. }
  118. $fRefTime = MyHelpers::getmicrotime();
  119. try
  120. {
  121. $sSql = MetaModel::MakeSelectQuery($oFilter, $aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount);
  122. }
  123. catch(Exception $e)
  124. {
  125. LogResult("Failed to create the SQL:".$e->getMessage());
  126. $sSql = '';
  127. }
  128. $fMakeDuration = MyHelpers::getmicrotime() - $fRefTime;
  129. }
  130. elseif ($aQueryData['type'] == 'group_by')
  131. {
  132. $aGroupByExpr = $aQueryData['group_by_expr'];
  133. $sQueryType = 'GROUP BY';
  134. $sQueryDesc = 'expr: '.serialize($aGroupByExpr);
  135. $fRefTime = MyHelpers::getmicrotime();
  136. try
  137. {
  138. $sSql = MetaModel::MakeGroupByQuery($oFilter, $aArgs, $aGroupByExpr);
  139. }
  140. catch(Exception $e)
  141. {
  142. LogResult("Failed to create the SQL:".$e->getMessage());
  143. $sSql = '';
  144. }
  145. $fMakeDuration = MyHelpers::getmicrotime() - $fRefTime;
  146. }
  147. else
  148. {
  149. // unsupported
  150. $sQueryType = 'ERROR';
  151. $sQueryDesc = "Unkown type of query: ".$aQueryData['type'];
  152. $fMakeDuration = 0;
  153. }
  154. LogResult($sOql);
  155. LogResult($sQueryType);
  156. if (strlen($sQueryDesc) > 0)
  157. {
  158. LogResult($sQueryDesc);
  159. }
  160. if ($sSql != '')
  161. {
  162. try
  163. {
  164. $fRefTime = MyHelpers::getmicrotime();
  165. $resQuery = CMDBSource::Query($sSql);
  166. $fExecDuration = MyHelpers::getmicrotime() - $fRefTime;
  167. $iTableCount = count(CMDBSource::ExplainQuery($sSql));
  168. }
  169. catch (Exception $e)
  170. {
  171. LogResult("Failed to execute the SQL:".$e->getMessage());
  172. LogResult("The failing SQL:\n".$sSql);
  173. $resQuery = null;
  174. $fExecDuration = 0;
  175. $iTableCount = 0;
  176. }
  177. $iRowCount = 0;
  178. if ($resQuery)
  179. {
  180. while ($aRow = CMDBSource::FetchArray($resQuery))
  181. {
  182. LogResult("row: ".serialize($aRow));
  183. $iRowCount++;
  184. }
  185. CMDBSource::FreeResult($resQuery);
  186. }
  187. LogResult("row count = ".$iRowCount);
  188. LogBenchmarkCSV($sOql, $sQueryType, $sQueryDesc, round($fMakeDuration, 3), $iTableCount, strlen($sSql), round($fExecDuration, 3), $iRowCount);
  189. }
  190. }
  191. }
  192. $oP->output();
  193. ?>