diff options
Diffstat (limited to 'includes/profiler')
-rw-r--r-- | includes/profiler/Profiler.php | 174 | ||||
-rw-r--r-- | includes/profiler/ProfilerSimple.php | 26 | ||||
-rw-r--r-- | includes/profiler/ProfilerSimpleText.php | 18 | ||||
-rw-r--r-- | includes/profiler/ProfilerSimpleTrace.php | 22 | ||||
-rw-r--r-- | includes/profiler/ProfilerSimpleUDP.php | 2 |
5 files changed, 135 insertions, 107 deletions
diff --git a/includes/profiler/Profiler.php b/includes/profiler/Profiler.php index 62be39e4..5ecdc4f0 100644 --- a/includes/profiler/Profiler.php +++ b/includes/profiler/Profiler.php @@ -28,7 +28,7 @@ /** * Begin profiling of a function - * @param $functionname String: name of the function we will profile + * @param string $functionname name of the function we will profile */ function wfProfileIn( $functionname ) { global $wgProfiler; @@ -39,7 +39,7 @@ function wfProfileIn( $functionname ) { /** * Stop profiling of a function - * @param $functionname String: name of the function we have profiled + * @param string $functionname name of the function we have profiled */ function wfProfileOut( $functionname = 'missing' ) { global $wgProfiler; @@ -157,7 +157,7 @@ class Profiler { */ public function profileIn( $functionname ) { global $wgDebugFunctionEntry; - if( $wgDebugFunctionEntry ){ + if( $wgDebugFunctionEntry ) { $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" ); } @@ -174,22 +174,22 @@ class Profiler { $memory = memory_get_usage(); $time = $this->getTime(); - if( $wgDebugFunctionEntry ){ + if( $wgDebugFunctionEntry ) { $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" ); } - $bit = array_pop($this->mWorkStack); + $bit = array_pop( $this->mWorkStack ); - if (!$bit) { - $this->debug("Profiling error, !\$bit: $functionname\n"); + if ( !$bit ) { + $this->debug( "Profiling error, !\$bit: $functionname\n" ); } else { - //if( $wgDebugProfiling ){ - if( $functionname == 'close' ){ + //if( $wgDebugProfiling ) { + if( $functionname == 'close' ) { $message = "Profile section ended by close(): {$bit[0]}"; $this->debug( "$message\n" ); $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 ); } - elseif( $bit[0] != $functionname ){ + elseif( $bit[0] != $functionname ) { $message = "Profiling error: in({$bit[0]}), out($functionname)"; $this->debug( "$message\n" ); $this->mStack[] = array( $message, 0, 0.0, 0, 0.0, 0 ); @@ -205,7 +205,7 @@ class Profiler { * Close opened profiling sections */ public function close() { - while( count( $this->mWorkStack ) ){ + while( count( $this->mWorkStack ) ) { $this->profileOut( 'close' ); } } @@ -228,7 +228,7 @@ class Profiler { global $wgDebugFunctionEntry, $wgProfileCallTree; $wgDebugFunctionEntry = false; - if( !count( $this->mStack ) && !count( $this->mCollated ) ){ + if( !count( $this->mStack ) && !count( $this->mCollated ) ) { return "No profiling output\n"; } @@ -250,20 +250,20 @@ class Profiler { /** * Recursive function the format the current profiling array into a tree * - * @param $stack array profiling array + * @param array $stack profiling array * @return array */ function remapCallTree( $stack ) { - if( count( $stack ) < 2 ){ + if( count( $stack ) < 2 ) { return $stack; } $outputs = array (); - for( $max = count( $stack ) - 1; $max > 0; ){ + for( $max = count( $stack ) - 1; $max > 0; ) { /* Find all items under this entry */ $level = $stack[$max][1]; $working = array (); - for( $i = $max -1; $i >= 0; $i-- ){ - if( $stack[$i][1] > $level ){ + for( $i = $max -1; $i >= 0; $i-- ) { + if( $stack[$i][1] > $level ) { $working[] = $stack[$i]; } else { break; @@ -271,7 +271,7 @@ class Profiler { } $working = $this->remapCallTree( array_reverse( $working ) ); $output = array(); - foreach( $working as $item ){ + foreach( $working as $item ) { array_push( $output, $item ); } array_unshift( $output, $stack[$max] ); @@ -280,8 +280,8 @@ class Profiler { array_unshift( $outputs, $output ); } $final = array(); - foreach( $outputs as $output ){ - foreach( $output as $item ){ + foreach( $outputs as $output ) { + foreach( $output as $item ) { $final[] = $item; } } @@ -293,9 +293,9 @@ class Profiler { * @return string */ function getCallTreeLine( $entry ) { - list( $fname, $level, $start, /* $x */, $end) = $entry; + list( $fname, $level, $start, /* $x */, $end ) = $entry; $delta = $end - $start; - $space = str_repeat(' ', $level); + $space = str_repeat( ' ', $level ); # The ugly double sprintf is to work around a PHP bug, # which has been fixed in recent releases. return sprintf( "%10s %s %s\n", trim( sprintf( "%7.3f", $delta * 1000.0 ) ), $space, $fname ); @@ -305,7 +305,7 @@ class Profiler { * Get the initial time of the request, based either on $wgRequestTime or * $wgRUstart. Will return null if not able to find data. * - * @param $metric string|false: metric to use, with the following possibilities: + * @param string|false $metric metric to use, with the following possibilities: * - user: User CPU time (without system calls) * - cpu: Total CPU time (user and system calls) * - wall (or any other string): elapsed time @@ -338,7 +338,7 @@ class Profiler { * Get the initial time of the request, based either on $wgRequestTime or * $wgRUstart. Will return null if not able to find data. * - * @param $metric string|false: metric to use, with the following possibilities: + * @param string|false $metric metric to use, with the following possibilities: * - user: User CPU time (without system calls) * - cpu: Total CPU time (user and system calls) * - wall (or any other string): elapsed time @@ -386,23 +386,23 @@ class Profiler { $this->mMemory = array(); # Estimate profiling overhead - $profileCount = count($this->mStack); + $profileCount = count( $this->mStack ); self::calculateOverhead( $profileCount ); # First, subtract the overhead! $overheadTotal = $overheadMemory = $overheadInternal = array(); - foreach( $this->mStack as $entry ){ + foreach( $this->mStack as $entry ) { $fname = $entry[0]; $start = $entry[2]; $end = $entry[4]; $elapsed = $end - $start; $memory = $entry[5] - $entry[3]; - if( $fname == '-overhead-total' ){ + if( $fname == '-overhead-total' ) { $overheadTotal[] = $elapsed; $overheadMemory[] = $memory; } - elseif( $fname == '-overhead-internal' ){ + elseif( $fname == '-overhead-internal' ) { $overheadInternal[] = $elapsed; } } @@ -411,7 +411,7 @@ class Profiler { $overheadInternal = $overheadInternal ? array_sum( $overheadInternal ) / count( $overheadInternal ) : 0; # Collate - foreach( $this->mStack as $index => $entry ){ + foreach( $this->mStack as $index => $entry ) { $fname = $entry[0]; $start = $entry[2]; $end = $entry[4]; @@ -420,7 +420,7 @@ class Profiler { $memory = $entry[5] - $entry[3]; $subcalls = $this->calltreeCount( $this->mStack, $index ); - if( !preg_match( '/^-overhead/', $fname ) ){ + if( !preg_match( '/^-overhead/', $fname ) ) { # Adjust for profiling overhead (except special values with elapsed=0 if( $elapsed ) { $elapsed -= $overheadInternal; @@ -429,7 +429,7 @@ class Profiler { } } - if( !array_key_exists( $fname, $this->mCollated ) ){ + if( !array_key_exists( $fname, $this->mCollated ) ) { $this->mCollated[$fname] = 0; $this->mCalls[$fname] = 0; $this->mMemory[$fname] = 0; @@ -441,8 +441,8 @@ class Profiler { $this->mCollated[$fname] += $elapsed; $this->mCalls[$fname]++; $this->mMemory[$fname] += $memory; - $this->mMin[$fname] = min($this->mMin[$fname], $elapsed); - $this->mMax[$fname] = max($this->mMax[$fname], $elapsed); + $this->mMin[$fname] = min( $this->mMin[$fname], $elapsed ); + $this->mMax[$fname] = max( $this->mMax[$fname], $elapsed ); $this->mOverhead[$fname] += $subcalls; } @@ -460,18 +460,18 @@ class Profiler { $width = 140; $nameWidth = $width - 65; - $format = "%-{$nameWidth}s %6d %13.3f %13.3f %13.3f%% %9d (%13.3f -%13.3f) [%d]\n"; + $format = "%-{$nameWidth}s %6d %13.3f %13.3f %13.3f%% %9d (%13.3f -%13.3f) [%d]\n"; $titleFormat = "%-{$nameWidth}s %6s %13s %13s %13s %9s\n"; $prof = "\nProfiling data\n"; $prof .= sprintf( $titleFormat, 'Name', 'Calls', 'Total', 'Each', '%', 'Mem' ); $total = isset( $this->mCollated['-total'] ) ? $this->mCollated['-total'] : 0; - foreach( $this->mCollated as $fname => $elapsed ){ + foreach( $this->mCollated as $fname => $elapsed ) { $calls = $this->mCalls[$fname]; $percent = $total ? 100. * $elapsed / $total : 0; $memory = $this->mMemory[$fname]; - $prof .= sprintf($format, substr($fname, 0, $nameWidth), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ($this->mMin[$fname] * 1000.0), ($this->mMax[$fname] * 1000.0), $this->mOverhead[$fname]); + $prof .= sprintf( $format, substr( $fname, 0, $nameWidth ), $calls, (float) ($elapsed * 1000), (float) ($elapsed * 1000) / $calls, $percent, $memory, ( $this->mMin[$fname] * 1000.0 ), ( $this->mMax[$fname] * 1000.0 ), $this->mOverhead[$fname] ); } $prof .= "\nTotal: $total\n\n"; @@ -483,7 +483,7 @@ class Profiler { */ protected static function calculateOverhead( $profileCount ) { wfProfileIn( '-overhead-total' ); - for( $i = 0; $i < $profileCount; $i++ ){ + for( $i = 0; $i < $profileCount; $i++ ) { wfProfileIn( '-overhead-internal' ); wfProfileOut( '-overhead-internal' ); } @@ -499,10 +499,10 @@ class Profiler { * @return Integer * @private */ - function calltreeCount($stack, $start) { + function calltreeCount( $stack, $start ) { $level = $stack[$start][1]; $count = 0; - for ($i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i --) { + for ( $i = $start -1; $i >= 0 && $stack[$i][1] > $level; $i-- ) { $count ++; } return $count; @@ -511,7 +511,7 @@ class Profiler { /** * Log the whole profiling data into the database. */ - public function logData(){ + public function logData() { global $wgProfilePerHost, $wgProfileToDatabase; # Do not log anything if database is readonly (bug 5375) @@ -524,52 +524,50 @@ class Profiler { return; } - $errorState = $dbw->ignoreErrors( true ); - - if( $wgProfilePerHost ){ + if( $wgProfilePerHost ) { $pfhost = wfHostname(); } else { $pfhost = ''; } - $this->collateData(); - - foreach( $this->mCollated as $name => $elapsed ){ - $eventCount = $this->mCalls[$name]; - $timeSum = (float) ($elapsed * 1000); - $memorySum = (float)$this->mMemory[$name]; - $name = substr($name, 0, 255); - - // Kludge - $timeSum = ($timeSum >= 0) ? $timeSum : 0; - $memorySum = ($memorySum >= 0) ? $memorySum : 0; - - $dbw->update( 'profiling', - array( - "pf_count=pf_count+{$eventCount}", - "pf_time=pf_time+{$timeSum}", - "pf_memory=pf_memory+{$memorySum}", - ), - array( - 'pf_name' => $name, - 'pf_server' => $pfhost, - ), - __METHOD__ ); - - $rc = $dbw->affectedRows(); - if ( $rc == 0 ) { - $dbw->insert('profiling', array ('pf_name' => $name, 'pf_count' => $eventCount, - 'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ), - __METHOD__, array ('IGNORE')); + try { + $this->collateData(); + + foreach( $this->mCollated as $name => $elapsed ) { + $eventCount = $this->mCalls[$name]; + $timeSum = (float) ($elapsed * 1000); + $memorySum = (float)$this->mMemory[$name]; + $name = substr($name, 0, 255); + + // Kludge + $timeSum = ($timeSum >= 0) ? $timeSum : 0; + $memorySum = ($memorySum >= 0) ? $memorySum : 0; + + $dbw->update( 'profiling', + array( + "pf_count=pf_count+{$eventCount}", + "pf_time=pf_time+{$timeSum}", + "pf_memory=pf_memory+{$memorySum}", + ), + array( + 'pf_name' => $name, + 'pf_server' => $pfhost, + ), + __METHOD__ ); + + $rc = $dbw->affectedRows(); + if ( $rc == 0 ) { + $dbw->insert( 'profiling', array ( 'pf_name' => $name, 'pf_count' => $eventCount, + 'pf_time' => $timeSum, 'pf_memory' => $memorySum, 'pf_server' => $pfhost ), + __METHOD__, array ( 'IGNORE' ) ); + } + // When we upgrade to mysql 4.1, the insert+update + // can be merged into just a insert with this construct added: + // "ON DUPLICATE KEY UPDATE ". + // "pf_count=pf_count + VALUES(pf_count), ". + // "pf_time=pf_time + VALUES(pf_time)"; } - // When we upgrade to mysql 4.1, the insert+update - // can be merged into just a insert with this construct added: - // "ON DUPLICATE KEY UPDATE ". - // "pf_count=pf_count + VALUES(pf_count), ". - // "pf_time=pf_time + VALUES(pf_time)"; - } - - $dbw->ignoreErrors( $errorState ); + } catch ( DBError $e ) {} } /** @@ -584,11 +582,25 @@ class Profiler { /** * Add an entry in the debug log file * - * @param $s String to output + * @param string $s to output */ function debug( $s ) { if( defined( 'MW_COMPILED' ) || function_exists( 'wfDebug' ) ) { wfDebug( $s ); } } + + /** + * Get the content type sent out to the client. + * Used for profilers that output instead of store data. + * @return string + */ + protected function getContentType() { + foreach ( headers_list() as $header ) { + if ( preg_match( '#^content-type: (\w+/\w+);?#i', $header, $m ) ) { + return $m[1]; + } + } + return null; + } } diff --git a/includes/profiler/ProfilerSimple.php b/includes/profiler/ProfilerSimple.php index d1d1c5d9..1d4873c6 100644 --- a/includes/profiler/ProfilerSimple.php +++ b/includes/profiler/ProfilerSimple.php @@ -29,7 +29,7 @@ class ProfilerSimple extends Profiler { var $mMinimumTime = 0; - var $zeroEntry = array('cpu'=> 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0); + var $zeroEntry = array( 'cpu' => 0.0, 'cpu_sq' => 0.0, 'real' => 0.0, 'real_sq' => 0.0, 'count' => 0 ); var $errorEntry; public function isPersistent() { @@ -57,33 +57,33 @@ class ProfilerSimple extends Profiler { $this->mMinimumTime = $min; } - function profileIn($functionname) { + function profileIn( $functionname ) { global $wgDebugFunctionEntry; - if ($wgDebugFunctionEntry) { - $this->debug(str_repeat(' ', count($this->mWorkStack)).'Entering '.$functionname."\n"); + if ( $wgDebugFunctionEntry ) { + $this->debug( str_repeat( ' ', count( $this->mWorkStack ) ) . 'Entering ' . $functionname . "\n" ); } $this->mWorkStack[] = array( $functionname, count( $this->mWorkStack ), $this->getTime(), $this->getTime( 'cpu' ) ); } - function profileOut($functionname) { + function profileOut( $functionname ) { global $wgDebugFunctionEntry; - if ($wgDebugFunctionEntry) { - $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); + if ( $wgDebugFunctionEntry ) { + $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" ); } - list($ofname, /* $ocount */ ,$ortime,$octime) = array_pop($this->mWorkStack); + list( $ofname, /* $ocount */, $ortime, $octime ) = array_pop( $this->mWorkStack ); - if (!$ofname) { - $this->debug("Profiling error: $functionname\n"); + if ( !$ofname ) { + $this->debug( "Profiling error: $functionname\n" ); } else { - if ($functionname == 'close') { + if ( $functionname == 'close' ) { $message = "Profile section ended by close(): {$ofname}"; $functionname = $ofname; $this->debug( "$message\n" ); $this->mCollated[$message] = $this->errorEntry; } - elseif ($ofname != $functionname) { + elseif ( $ofname != $functionname ) { $message = "Profiling error: in({$ofname}), out($functionname)"; $this->debug( "$message\n" ); $this->mCollated[$message] = $this->errorEntry; @@ -91,7 +91,7 @@ class ProfilerSimple extends Profiler { $entry =& $this->mCollated[$functionname]; $elapsedcpu = $this->getTime( 'cpu' ) - $octime; $elapsedreal = $this->getTime() - $ortime; - if (!is_array($entry)) { + if ( !is_array( $entry ) ) { $entry = $this->zeroEntry; $this->mCollated[$functionname] =& $entry; } diff --git a/includes/profiler/ProfilerSimpleText.php b/includes/profiler/ProfilerSimpleText.php index 3e7d6fa4..37350bf3 100644 --- a/includes/profiler/ProfilerSimpleText.php +++ b/includes/profiler/ProfilerSimpleText.php @@ -48,12 +48,20 @@ class ProfilerSimpleText extends ProfilerSimple { $totalReal = isset( $this->mCollated['-total'] ) ? $this->mCollated['-total']['real'] : 0; // profiling mismatch error? - uasort( $this->mCollated, array('self','sort') ); - array_walk( $this->mCollated, array('self','format'), $totalReal ); - if ( $this->visible ) { - print '<pre>'.self::$out.'</pre>'; - } else { + uasort( $this->mCollated, array( 'self', 'sort' ) ); + array_walk( $this->mCollated, array( 'self', 'format' ), $totalReal ); + if ( PHP_SAPI === 'cli' ) { print "<!--\n".self::$out."\n-->\n"; + } elseif ( $this->getContentType() === 'text/html' ) { + if ( $this->visible ) { + print '<pre>'.self::$out.'</pre>'; + } else { + print "<!--\n".self::$out."\n-->\n"; + } + } elseif ( $this->getContentType() === 'text/javascript' ) { + print "\n/*\n".self::$out."*/\n"; + } elseif ( $this->getContentType() === 'text/css' ) { + print "\n/*\n".self::$out."*/\n"; } } } diff --git a/includes/profiler/ProfilerSimpleTrace.php b/includes/profiler/ProfilerSimpleTrace.php index 822e9fe4..d44dfe1b 100644 --- a/includes/profiler/ProfilerSimpleTrace.php +++ b/includes/profiler/ProfilerSimpleTrace.php @@ -32,18 +32,18 @@ class ProfilerSimpleTrace extends ProfilerSimple { function profileIn( $functionname ) { parent::profileIn( $functionname ); - $this->trace .= " " . sprintf("%6.1f",$this->memoryDiff()) . - str_repeat( " ", count($this->mWorkStack)) . " > " . $functionname . "\n"; + $this->trace .= " " . sprintf( "%6.1f", $this->memoryDiff() ) . + str_repeat( " ", count( $this->mWorkStack ) ) . " > " . $functionname . "\n"; } - function profileOut($functionname) { + function profileOut( $functionname ) { global $wgDebugFunctionEntry; if ( $wgDebugFunctionEntry ) { - $this->debug(str_repeat(' ', count($this->mWorkStack) - 1).'Exiting '.$functionname."\n"); + $this->debug( str_repeat( ' ', count( $this->mWorkStack ) - 1 ) . 'Exiting ' . $functionname . "\n" ); } - list( $ofname, /* $ocount */ , $ortime ) = array_pop( $this->mWorkStack ); + list( $ofname, /* $ocount */, $ortime ) = array_pop( $this->mWorkStack ); if ( !$ofname ) { $this->trace .= "Profiling error: $functionname\n"; @@ -58,7 +58,7 @@ class ProfilerSimpleTrace extends ProfilerSimple { } $elapsedreal = $this->getTime() - $ortime; $this->trace .= sprintf( "%03.6f %6.1f", $elapsedreal, $this->memoryDiff() ) . - str_repeat(" ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n"; + str_repeat( " ", count( $this->mWorkStack ) + 1 ) . " < " . $functionname . "\n"; } } @@ -69,6 +69,14 @@ class ProfilerSimpleTrace extends ProfilerSimple { } function logData() { - print "<!-- \n {$this->trace} \n -->"; + if ( PHP_SAPI === 'cli' ) { + print "<!-- \n {$this->trace} \n -->"; + } elseif ( $this->getContentType() === 'text/html' ) { + print "<!-- \n {$this->trace} \n -->"; + } elseif ( $this->getContentType() === 'text/javascript' ) { + print "\n/*\n {$this->trace}\n*/"; + } elseif ( $this->getContentType() === 'text/css' ) { + print "\n/*\n {$this->trace}\n*/"; + } } } diff --git a/includes/profiler/ProfilerSimpleUDP.php b/includes/profiler/ProfilerSimpleUDP.php index a95ccb0d..abefa811 100644 --- a/includes/profiler/ProfilerSimpleUDP.php +++ b/includes/profiler/ProfilerSimpleUDP.php @@ -50,7 +50,7 @@ class ProfilerSimpleUDP extends ProfilerSimple { $plength = 0; $packet = ""; foreach ( $this->mCollated as $entry => $pfdata ) { - if( !isset($pfdata['count']) + if( !isset( $pfdata['count'] ) || !isset( $pfdata['cpu'] ) || !isset( $pfdata['cpu_sq'] ) || !isset( $pfdata['real'] ) |