replay_query_log.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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('type', 'properties', 'make duration', 'class', 'tables', 'query length', 'exec duration', 'rows', 'oql');
  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. $sClass = $oFilter->GetClass();
  91. $aArgs = $aQueryData['args'];
  92. if ($aQueryData['type'] == 'select')
  93. {
  94. $aOrderBy = $aQueryData['order_by'];
  95. $aAttToLoad = $aQueryData['att_to_load'];
  96. $aExtendedDataSpec = $aQueryData['extended_data_spec'];
  97. $iLimitCount = $aQueryData['limit_count'];
  98. $iLimitStart = $aQueryData['limit_start'];
  99. $bGetCount = $aQueryData['is_count'];
  100. if ($bGetCount)
  101. {
  102. $sQueryType = 'COUNT';
  103. $sQueryDesc = '';
  104. }
  105. else
  106. {
  107. $sQueryType = 'LIST';
  108. $sQueryDesc = "limit count: $iLimitCount";
  109. $sQueryDesc .= "; limit start: $iLimitStart";
  110. if (count($aOrderBy) > 0)
  111. {
  112. $sQueryDesc .= "; order by: ".implode(',', array_keys($aOrderBy));
  113. }
  114. if (is_array($aAttToLoad))
  115. {
  116. $sQueryDesc .= "; attributes: ".implode(',', array_keys($aAttToLoad));
  117. }
  118. }
  119. $fRefTime = MyHelpers::getmicrotime();
  120. try
  121. {
  122. $sSql = MetaModel::MakeSelectQuery($oFilter, $aOrderBy, $aArgs, $aAttToLoad, $aExtendedDataSpec, $iLimitCount, $iLimitStart, $bGetCount);
  123. }
  124. catch(Exception $e)
  125. {
  126. LogResult("Failed to create the SQL:".$e->getMessage());
  127. $sSql = '';
  128. }
  129. $fMakeDuration = MyHelpers::getmicrotime() - $fRefTime;
  130. }
  131. elseif ($aQueryData['type'] == 'group_by')
  132. {
  133. $aGroupByExpr = $aQueryData['group_by_expr'];
  134. $sQueryType = 'GROUP BY';
  135. $sQueryDesc = 'expr: '.serialize($aGroupByExpr);
  136. $fRefTime = MyHelpers::getmicrotime();
  137. try
  138. {
  139. $sSql = MetaModel::MakeGroupByQuery($oFilter, $aArgs, $aGroupByExpr);
  140. }
  141. catch(Exception $e)
  142. {
  143. LogResult("Failed to create the SQL:".$e->getMessage());
  144. $sSql = '';
  145. }
  146. $fMakeDuration = MyHelpers::getmicrotime() - $fRefTime;
  147. }
  148. else
  149. {
  150. // unsupported
  151. $sQueryType = 'ERROR';
  152. $sQueryDesc = "Unkown type of query: ".$aQueryData['type'];
  153. $fMakeDuration = 0;
  154. }
  155. LogResult($sOql);
  156. LogResult($sQueryType);
  157. if (strlen($sQueryDesc) > 0)
  158. {
  159. LogResult($sQueryDesc);
  160. }
  161. if ($sSql != '')
  162. {
  163. try
  164. {
  165. $fRefTime = MyHelpers::getmicrotime();
  166. $resQuery = CMDBSource::Query($sSql);
  167. $fExecDuration = MyHelpers::getmicrotime() - $fRefTime;
  168. $iTableCount = count(CMDBSource::ExplainQuery($sSql));
  169. }
  170. catch (Exception $e)
  171. {
  172. LogResult("Failed to execute the SQL:".$e->getMessage());
  173. LogResult("The failing SQL:\n".$sSql);
  174. $resQuery = null;
  175. $fExecDuration = 0;
  176. $iTableCount = 0;
  177. }
  178. $iRowCount = 0;
  179. if ($resQuery)
  180. {
  181. while ($aRow = CMDBSource::FetchArray($resQuery))
  182. {
  183. LogResult("row: ".serialize($aRow));
  184. $iRowCount++;
  185. }
  186. CMDBSource::FreeResult($resQuery);
  187. }
  188. LogResult("row count = ".$iRowCount);
  189. LogBenchmarkCSV($sQueryType, $sQueryDesc, round($fMakeDuration, 3), $sClass, $iTableCount, strlen($sSql), round($fExecDuration, 3), $iRowCount, $sOql);
  190. }
  191. }
  192. }
  193. $oP->output();
  194. ?>