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>