00001 <?php 00002 ini_set( 'zlib.output_compression', 'off' ); 00003 00004 $wgDBadminuser = $wgDBadminpassword = $wgDBserver = $wgDBname = $wgDBprefix = false; 00005 $wgEnableProfileInfo = $wgProfileToDatabase = false; 00006 00007 define( 'MW_NO_SETUP', 1 ); 00008 require_once( './includes/WebStart.php' ); 00009 @include_once( './AdminSettings.php' ); 00010 require_once( './includes/GlobalFunctions.php' ); 00011 00012 ?> 00013 <!-- 00014 Show profiling data. 00015 00016 Copyright 2005 Kate Turner. 00017 00018 Permission is hereby granted, free of charge, to any person obtaining a copy 00019 of this software and associated documentation files (the "Software"), to deal 00020 in the Software without restriction, including without limitation the rights 00021 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00022 copies of the Software, and to permit persons to whom the Software is 00023 furnished to do so, subject to the following conditions: 00024 00025 The above copyright notice and this permission notice shall be included in 00026 all copies or substantial portions of the Software. 00027 00028 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00029 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00030 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00031 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00032 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00033 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00034 SOFTWARE. 00035 00036 --> 00037 <html> 00038 <head> 00039 <title>Profiling data</title> 00040 <style type="text/css"> 00041 th { 00042 text-align: left; 00043 border-bottom: solid 1px black; 00044 } 00045 00046 th, td { 00047 padding-left: 0.5em; 00048 padding-right: 0.5em; 00049 } 00050 00051 td.timep, td.memoryp, td.count, td.cpr, td.tpc, td.mpc, td.tpr, td.mpr { 00052 text-align: right; 00053 } 00054 td.timep, td.tpc, td.tpr { 00055 background-color: #fffff0; 00056 } 00057 td.memoryp, td.mpc, td.mpr { 00058 background-color: #f0f8ff; 00059 } 00060 td.count, td,cpr { 00061 background-color: #f0fff0; 00062 } 00063 td.name { 00064 background-color: #f9f9f9; 00065 } 00066 </style> 00067 </head> 00068 <body> 00069 <?php 00070 00071 if (!$wgEnableProfileInfo) { 00072 echo "<p>Disabled</p>\n"; 00073 echo "</body></html>"; 00074 exit( 1 ); 00075 } 00076 00077 foreach (array("wgDBadminuser", "wgDBadminpassword", "wgDBserver", "wgDBname") as $var) 00078 if ($$var === false) { 00079 echo "AdminSettings.php not correct\n"; 00080 exit( 1 ); 00081 } 00082 00083 00084 $expand = array(); 00085 if (isset($_REQUEST['expand'])) 00086 foreach(explode(",", $_REQUEST['expand']) as $f) 00087 $expand[$f] = true; 00088 00089 class profile_point { 00090 var $name; 00091 var $count; 00092 var $time; 00093 var $children; 00094 00095 function profile_point($name, $count, $time, $memory ) { 00096 $this->name = $name; 00097 $this->count = $count; 00098 $this->time = $time; 00099 $this->memory = $memory; 00100 $this->children = array(); 00101 } 00102 00103 function add_child($child) { 00104 $this->children[] = $child; 00105 } 00106 00107 function display($indent = 0.0) { 00108 global $expand, $totaltime, $totalmemory, $totalcount; 00109 usort($this->children, "compare_point"); 00110 00111 $extet = ''; 00112 if (isset($expand[$this->name()])) 00113 $ex = true; 00114 else $ex = false; 00115 if (!$ex) { 00116 if (count($this->children)) { 00117 $url = getEscapedProfileUrl(false, false, $expand + array($this->name() => true)); 00118 $extet = " <a href=\"$url\">[+]</a>"; 00119 } else $extet = ''; 00120 } else { 00121 $e = array(); 00122 foreach ($expand as $name => $ep) 00123 if ($name != $this->name()) 00124 $e += array($name => $ep); 00125 00126 $extet = " <a href=\"" . getEscapedProfileUrl(false, false, $e) . "\">[–]</a>"; 00127 } 00128 ?> 00129 <tr> 00130 <td class="name" style="padding-left: <?php echo $indent ?>em;"> 00131 <?php echo htmlspecialchars($this->name()) . $extet ?> 00132 </td> 00133 <td class="timep"><?php echo @wfPercent( $this->time() / $totaltime * 100 ) ?></td> 00134 <td class="memoryp"><?php echo @wfPercent( $this->memory() / $totalmemory * 100 ) ?></td> 00135 <td class="count"><?php echo $this->count() ?></td> 00136 <td class="cpr"><?php echo round( sprintf( '%.2f', $this->callsPerRequest() ), 2 ) ?></td> 00137 <td class="tpc"><?php echo round( sprintf( '%.2f', $this->timePerCall() ), 2 ) ?></td> 00138 <td class="mpc"><?php echo round( sprintf( '%.2f' ,$this->memoryPerCall() / 1024 ), 2 ) ?></td> 00139 <td class="tpr"><?php echo @round( sprintf( '%.2f', $this->time() / $totalcount ), 2 ) ?></td> 00140 <td class="mpr"><?php echo @round( sprintf( '%.2f' ,$this->memory() / $totalcount / 1024 ), 2 ) ?></td> 00141 </tr> 00142 <?php 00143 if ($ex) { 00144 foreach ($this->children as $child) { 00145 $child->display($indent + 2); 00146 } 00147 } 00148 } 00149 00150 function name() { 00151 return $this->name; 00152 } 00153 00154 function count() { 00155 return $this->count; 00156 } 00157 00158 function time() { 00159 return $this->time; 00160 } 00161 00162 function memory() { 00163 return $this->memory; 00164 } 00165 00166 function timePerCall() { 00167 return @($this->time / $this->count); 00168 } 00169 00170 function memoryPerCall() { 00171 return @($this->memory / $this->count); 00172 } 00173 00174 function callsPerRequest() { 00175 global $totalcount; 00176 return @($this->count / $totalcount); 00177 } 00178 00179 function timePerRequest() { 00180 global $totalcount; 00181 return @($this->time / $totalcount); 00182 } 00183 00184 function memoryPerRequest() { 00185 global $totalcount; 00186 return @($this->memory / $totalcount); 00187 } 00188 00189 function fmttime() { 00190 return sprintf("%5.02f", $this->time); 00191 } 00192 }; 00193 00194 function compare_point($a, $b) { 00195 global $sort; 00196 switch ($sort) { 00197 case "name": 00198 return strcmp($a->name(), $b->name()); 00199 case "time": 00200 return $a->time() > $b->time() ? -1 : 1; 00201 case "memory": 00202 return $a->memory() > $b->memory() ? -1 : 1; 00203 case "count": 00204 return $a->count() > $b->count() ? -1 : 1; 00205 case "time_per_call": 00206 return $a->timePerCall() > $b->timePerCall() ? -1 : 1; 00207 case "memory_per_call": 00208 return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1; 00209 case "calls_per_req": 00210 return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1; 00211 case "time_per_req": 00212 return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1; 00213 case "memory_per_req": 00214 return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1; 00215 } 00216 } 00217 00218 $sorts = array("time","memory","count","calls_per_req","name","time_per_call","memory_per_call","time_per_req","memory_per_req"); 00219 $sort = 'time'; 00220 if (isset($_REQUEST['sort']) && in_array($_REQUEST['sort'], $sorts)) 00221 $sort = $_REQUEST['sort']; 00222 00223 $dbh = mysql_connect($wgDBserver, $wgDBadminuser, $wgDBadminpassword) 00224 or die("mysql server failed: " . mysql_error()); 00225 mysql_select_db($wgDBname, $dbh) or die(mysql_error($dbh)); 00226 $res = mysql_query(" 00227 SELECT pf_count, pf_time, pf_memory, pf_name 00228 FROM {$wgDBprefix}profiling 00229 ORDER BY pf_name ASC 00230 ", $dbh) or die("query failed: " . mysql_error()); 00231 00232 if (isset($_REQUEST['filter'])) 00233 $filter = $_REQUEST['filter']; 00234 else $filter = ''; 00235 00236 ?> 00237 <form method="profiling.php"> 00238 <p> 00239 <input type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>"/> 00240 <input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort)?>"/> 00241 <input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand)))?>"/> 00242 <input type="submit" value="Filter" /> 00243 </p> 00244 </form> 00245 00246 <table cellspacing="0" border="1"> 00247 <tr id="top"> 00248 <th><a href="<?php echo getEscapedProfileUrl(false, "name") ?>">Name</a></th> 00249 <th><a href="<?php echo getEscapedProfileUrl(false, "time") ?>">Time (%)</a></th> 00250 <th><a href="<?php echo getEscapedProfileUrl(false, "memory") ?>">Memory (%)</a></th> 00251 <th><a href="<?php echo getEscapedProfileUrl(false, "count") ?>">Count</a></th> 00252 <th><a href="<?php echo getEscapedProfileUrl(false, "calls_per_req") ?>">Calls/req</a></th> 00253 <th><a href="<?php echo getEscapedProfileUrl(false, "time_per_call") ?>">ms/call</a></th> 00254 <th><a href="<?php echo getEscapedProfileUrl(false, "memory_per_call") ?>">kb/call</a></th> 00255 <th><a href="<?php echo getEscapedProfileUrl(false, "time_per_req") ?>">ms/req</a></th> 00256 <th><a href="<?php echo getEscapedProfileUrl(false, "memory_per_req") ?>">kb/req</a></th> 00257 </tr> 00258 <?php 00259 $totaltime = 0.0; 00260 $totalcount = 0; 00261 $totalmemory = 0.0; 00262 00263 function getEscapedProfileUrl( $_filter = false, $_sort = false, $_expand = false ) { 00264 global $filter, $sort, $expand; 00265 00266 if ( $_expand === false ) 00267 $_expand = $expand; 00268 00269 return htmlspecialchars( 00270 '?' . 00271 wfArrayToCGI( array( 00272 'filter' => $_filter ? $_filter : $filter, 00273 'sort' => $_sort ? $_sort : $sort, 00274 'expand' => implode( ',', array_keys( $_expand ) ) 00275 ) ) 00276 ); 00277 } 00278 00279 $points = array(); 00280 $queries = array(); 00281 $sqltotal = 0.0; 00282 00283 $last = false; 00284 while (($o = mysql_fetch_object($res)) !== false) { 00285 $next = new profile_point($o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory); 00286 if( $next->name() == '-total' ) { 00287 $totaltime = $next->time(); 00288 $totalcount = $next->count(); 00289 $totalmemory = $next->memory(); 00290 } 00291 if ($last !== false) { 00292 if (preg_match("/^".preg_quote($last->name(), "/")."/", $next->name())) { 00293 $last->add_child($next); 00294 continue; 00295 } 00296 } 00297 $last = $next; 00298 if (preg_match("/^query: /", $next->name()) || preg_match("/^query-m: /", $next->name())) { 00299 $sqltotal += $next->time(); 00300 $queries[] = $next; 00301 } else { 00302 $points[] = $next; 00303 } 00304 } 00305 00306 $s = new profile_point("SQL Queries", 0, $sqltotal, 0, 0); 00307 foreach ($queries as $q) 00308 $s->add_child($q); 00309 $points[] = $s; 00310 00311 usort($points, "compare_point"); 00312 00313 foreach ($points as $point) { 00314 if (strlen($filter) && !strstr($point->name(), $filter)) 00315 continue; 00316 00317 $point->display(); 00318 } 00319 ?> 00320 </table> 00321 00322 <p>Total time: <tt><?php printf("%5.02f", $totaltime) ?></tt></p> 00323 <p>Total memory: <tt><?php printf("%5.02f", $totalmemory / 1024 ) ?></tt></p> 00324 <?php 00325 00326 mysql_free_result($res); 00327 mysql_close($dbh); 00328 00329 ?> 00330 </body> 00331 </html>