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 "disabled\n"; 00073 exit( 1 ); 00074 } 00075 00076 foreach (array("wgDBadminuser", "wgDBadminpassword", "wgDBserver", "wgDBname") as $var) 00077 if ($$var === false) { 00078 echo "AdminSettings.php not correct\n"; 00079 exit( 1 ); 00080 } 00081 00082 00083 $expand = array(); 00084 if (isset($_REQUEST['expand'])) 00085 foreach(explode(",", $_REQUEST['expand']) as $f) 00086 $expand[$f] = true; 00087 00088 class profile_point { 00089 var $name; 00090 var $count; 00091 var $time; 00092 var $children; 00093 00094 function profile_point($name, $count, $time, $memory ) { 00095 $this->name = $name; 00096 $this->count = $count; 00097 $this->time = $time; 00098 $this->memory = $memory; 00099 $this->children = array(); 00100 } 00101 00102 function add_child($child) { 00103 $this->children[] = $child; 00104 } 00105 00106 function display($indent = 0.0) { 00107 global $expand, $totaltime, $totalmemory, $totalcount; 00108 usort($this->children, "compare_point"); 00109 00110 $extet = ''; 00111 if (isset($expand[$this->name()])) 00112 $ex = true; 00113 else $ex = false; 00114 if (!$ex) { 00115 if (count($this->children)) { 00116 $url = makeurl(false, false, $expand + array($this->name() => true)); 00117 $extet = " <a href=\"$url\">[+]</a>"; 00118 } else $extet = ''; 00119 } else { 00120 $e = array(); 00121 foreach ($expand as $name => $ep) 00122 if ($name != $this->name()) 00123 $e += array($name => $ep); 00124 00125 $extet = " <a href=\"" . makeurl(false, false, $e) . "\">[–]</a>"; 00126 } 00127 ?> 00128 <tr> 00129 <td class="name" style="padding-left: <?php echo $indent ?>em;"> 00130 <?php echo htmlspecialchars($this->name()) . $extet ?> 00131 </td> 00132 <td class="timep"><?php echo @wfPercent( $this->time() / $totaltime * 100 ) ?></td> 00133 <td class="memoryp"><?php echo @wfPercent( $this->memory() / $totalmemory * 100 ) ?></td> 00134 <td class="count"><?php echo $this->count() ?></td> 00135 <td class="cpr"><?php echo round( sprintf( '%.2f', $this->callsPerRequest() ), 2 ) ?></td> 00136 <td class="tpc"><?php echo round( sprintf( '%.2f', $this->timePerCall() ), 2 ) ?></td> 00137 <td class="mpc"><?php echo round( sprintf( '%.2f' ,$this->memoryPerCall() / 1024 ), 2 ) ?></td> 00138 <td class="tpr"><?php echo @round( sprintf( '%.2f', $this->time() / $totalcount ), 2 ) ?></td> 00139 <td class="mpr"><?php echo @round( sprintf( '%.2f' ,$this->memory() / $totalcount / 1024 ), 2 ) ?></td> 00140 </tr> 00141 <?php 00142 if ($ex) { 00143 foreach ($this->children as $child) { 00144 $child->display($indent + 2); 00145 } 00146 } 00147 } 00148 00149 function name() { 00150 return $this->name; 00151 } 00152 00153 function count() { 00154 return $this->count; 00155 } 00156 00157 function time() { 00158 return $this->time; 00159 } 00160 00161 function memory() { 00162 return $this->memory; 00163 } 00164 00165 function timePerCall() { 00166 return @($this->time / $this->count); 00167 } 00168 00169 function memoryPerCall() { 00170 return @($this->memory / $this->count); 00171 } 00172 00173 function callsPerRequest() { 00174 global $totalcount; 00175 return @($this->count / $totalcount); 00176 } 00177 00178 function timePerRequest() { 00179 global $totalcount; 00180 return @($this->time / $totalcount); 00181 } 00182 00183 function memoryPerRequest() { 00184 global $totalcount; 00185 return @($this->memory / $totalcount); 00186 } 00187 00188 function fmttime() { 00189 return sprintf("%5.02f", $this->time); 00190 } 00191 }; 00192 00193 function compare_point($a, $b) { 00194 global $sort; 00195 switch ($sort) { 00196 case "name": 00197 return strcmp($a->name(), $b->name()); 00198 case "time": 00199 return $a->time() > $b->time() ? -1 : 1; 00200 case "memory": 00201 return $a->memory() > $b->memory() ? -1 : 1; 00202 case "count": 00203 return $a->count() > $b->count() ? -1 : 1; 00204 case "time_per_call": 00205 return $a->timePerCall() > $b->timePerCall() ? -1 : 1; 00206 case "memory_per_call": 00207 return $a->memoryPerCall() > $b->memoryPerCall() ? -1 : 1; 00208 case "calls_per_req": 00209 return $a->callsPerRequest() > $b->callsPerRequest() ? -1 : 1; 00210 case "time_per_req": 00211 return $a->timePerRequest() > $b->timePerRequest() ? -1 : 1; 00212 case "memory_per_req": 00213 return $a->memoryPerRequest() > $b->memoryPerRequest() ? -1 : 1; 00214 } 00215 } 00216 00217 $sorts = array("time","memory","count","calls_per_req","name","time_per_call","memory_per_call","time_per_req","memory_per_req"); 00218 $sort = 'time'; 00219 if (isset($_REQUEST['sort']) && in_array($_REQUEST['sort'], $sorts)) 00220 $sort = $_REQUEST['sort']; 00221 00222 $dbh = mysql_connect($wgDBserver, $wgDBadminuser, $wgDBadminpassword) 00223 or die("mysql server failed: " . mysql_error()); 00224 mysql_select_db($wgDBname, $dbh) or die(mysql_error($dbh)); 00225 $res = mysql_query(" 00226 SELECT pf_count, pf_time, pf_memory, pf_name 00227 FROM {$wgDBprefix}profiling 00228 ORDER BY pf_name ASC 00229 ", $dbh) or die("query failed: " . mysql_error()); 00230 00231 if (isset($_REQUEST['filter'])) 00232 $filter = $_REQUEST['filter']; 00233 else $filter = ''; 00234 00235 ?> 00236 <form method="profiling.php"> 00237 <p> 00238 <input type="text" name="filter" value="<?php echo htmlspecialchars($filter)?>"/> 00239 <input type="hidden" name="sort" value="<?php echo htmlspecialchars($sort)?>"/> 00240 <input type="hidden" name="expand" value="<?php echo htmlspecialchars(implode(",", array_keys($expand)))?>"/> 00241 <input type="submit" value="Filter" /> 00242 </p> 00243 </form> 00244 00245 <table cellspacing="0" border="1"> 00246 <tr id="top"> 00247 <th><a href="<?php echo makeurl(false, "name") ?>">Name</a></th> 00248 <th><a href="<?php echo makeurl(false, "time") ?>">Time (%)</a></th> 00249 <th><a href="<?php echo makeurl(false, "memory") ?>">Memory (%)</a></th> 00250 <th><a href="<?php echo makeurl(false, "count") ?>">Count</a></th> 00251 <th><a href="<?php echo makeurl(false, "calls_per_req") ?>">Calls/req</a></th> 00252 <th><a href="<?php echo makeurl(false, "time_per_call") ?>">ms/call</a></th> 00253 <th><a href="<?php echo makeurl(false, "memory_per_call") ?>">kb/call</a></th> 00254 <th><a href="<?php echo makeurl(false, "time_per_req") ?>">ms/req</a></th> 00255 <th><a href="<?php echo makeurl(false, "memory_per_req") ?>">kb/req</a></th> 00256 </tr> 00257 <?php 00258 $totaltime = 0.0; 00259 $totalcount = 0; 00260 $totalmemory = 0.0; 00261 00262 function makeurl($_filter = false, $_sort = false, $_expand = false) { 00263 global $filter, $sort, $expand; 00264 00265 if ($_expand === false) 00266 $_expand = $expand; 00267 00268 $nfilter = $_filter ? $_filter : $filter; 00269 $nsort = $_sort ? $_sort : $sort; 00270 $exp = urlencode(implode(',', array_keys($_expand))); 00271 return "?filter=$nfilter&sort=$nsort&expand=$exp"; 00272 } 00273 00274 $points = array(); 00275 $queries = array(); 00276 $sqltotal = 0.0; 00277 00278 $last = false; 00279 while (($o = mysql_fetch_object($res)) !== false) { 00280 $next = new profile_point($o->pf_name, $o->pf_count, $o->pf_time, $o->pf_memory); 00281 if( $next->name() == '-total' ) { 00282 $totaltime = $next->time(); 00283 $totalcount = $next->count(); 00284 $totalmemory = $next->memory(); 00285 } 00286 if ($last !== false) { 00287 if (preg_match("/^".preg_quote($last->name(), "/")."/", $next->name())) { 00288 $last->add_child($next); 00289 continue; 00290 } 00291 } 00292 $last = $next; 00293 if (preg_match("/^query: /", $next->name()) || preg_match("/^query-m: /", $next->name())) { 00294 $sqltotal += $next->time(); 00295 $queries[] = $next; 00296 } else { 00297 $points[] = $next; 00298 } 00299 } 00300 00301 $s = new profile_point("SQL Queries", 0, $sqltotal, 0, 0); 00302 foreach ($queries as $q) 00303 $s->add_child($q); 00304 $points[] = $s; 00305 00306 usort($points, "compare_point"); 00307 00308 foreach ($points as $point) { 00309 if (strlen($filter) && !strstr($point->name(), $filter)) 00310 continue; 00311 00312 $point->display(); 00313 } 00314 ?> 00315 </table> 00316 00317 <p>Total time: <tt><?php printf("%5.02f", $totaltime) ?></tt></p> 00318 <p>Total memory: <tt><?php printf("%5.02f", $totalmemory / 1024 ) ?></tt></p> 00319 <?php 00320 00321 mysql_free_result($res); 00322 mysql_close($dbh); 00323 00324 ?> 00325 </body> 00326 </html>