X-Git-Url: http://git.cyclocoop.org/%22%20.%20generer_url_ecrire%28%22auteur_infos%22%2C%22id_auteur=%24connect_id_auteur%22%29%20.%20%22?a=blobdiff_plain;f=includes%2Fprofiler%2FProfiler.php;h=dbf80fa13b99d5347c695dabf693ac2ed767bc71;hb=27b9c0639d976e8048330c7ee95be30f61ee941b;hp=4b7420699f27fdf4b8532b1f43012e89f7b29c98;hpb=4ac9dbee4a1c0688da6dfa91e8c6419c1bd16f69;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/profiler/Profiler.php b/includes/profiler/Profiler.php index 4b7420699f..dbf80fa13b 100644 --- a/includes/profiler/Profiler.php +++ b/includes/profiler/Profiler.php @@ -35,19 +35,10 @@ abstract class Profiler { protected $templated = false; /** @var array All of the params passed from $wgProfiler */ protected $params = array(); - + /** @var IContextSource Current request context */ + protected $context = null; /** @var TransactionProfiler */ protected $trxProfiler; - - /** - * @var array Mapping of output type to class name - */ - private static $outputTypes = array( - 'db' => 'ProfilerOutputDb', - 'text' => 'ProfilerOutputText', - 'udp' => 'ProfilerOutputUdp', - ); - /** @var Profiler */ private static $instance = null; @@ -68,17 +59,28 @@ abstract class Profiler { */ final public static function instance() { if ( self::$instance === null ) { - global $wgProfiler; + global $wgProfiler, $wgProfileLimit; + + $params = array( + 'class' => 'ProfilerStub', + 'sampling' => 1, + 'threshold' => $wgProfileLimit, + 'output' => array(), + ); if ( is_array( $wgProfiler ) ) { - $class = isset( $wgProfiler['class'] ) ? $wgProfiler['class'] : 'ProfilerStub'; - $factor = isset( $wgProfiler['sampling'] ) ? $wgProfiler['sampling'] : 1; - if ( PHP_SAPI === 'cli' || mt_rand( 0, $factor - 1 ) != 0 ) { - $class = 'ProfilerStub'; - } - self::$instance = new $class( $wgProfiler ); - } else { - self::$instance = new ProfilerStub( array() ); + $params = array_merge( $params, $wgProfiler ); + } + + $inSample = mt_rand( 0, $params['sampling'] - 1 ) === 0; + if ( PHP_SAPI === 'cli' || !$inSample ) { + $params['class'] = 'ProfilerStub'; + } + + if ( !is_array( $params['output'] ) ) { + $params['output'] = array( $params['output'] ); } + + self::$instance = new $params['class']( $params ); } return self::$instance; } @@ -116,6 +118,32 @@ abstract class Profiler { } } + /** + * Sets the context for this Profiler + * + * @param IContextSource $context + * @since 1.25 + */ + public function setContext( $context ) { + $this->context = $context; + } + + /** + * Gets the context for this Profiler + * + * @return IContextSource + * @since 1.25 + */ + public function getContext() { + if ( $this->context ) { + return $this->context; + } else { + wfDebug( __METHOD__ . " called and \$context is null. " . + "Return RequestContext::getMain(); for sanity\n" ); + return RequestContext::getMain(); + } + } + // Kept BC for now, remove when possible public function profileIn( $functionname ) {} public function profileOut( $functionname ) {} @@ -133,7 +161,7 @@ abstract class Profiler { /** * @param ScopedCallback $section */ - public function scopedProfileOut( ScopedCallback &$section ) { + public function scopedProfileOut( ScopedCallback &$section = null ) { $section = null; } @@ -151,34 +179,54 @@ abstract class Profiler { abstract public function close(); /** - * Log the data to some store or even the page output + * Get all usable outputs. * * @throws MWException + * @return array Array of ProfilerOutput instances. + * @since 1.25 + */ + private function getOutputs() { + $outputs = array(); + foreach ( $this->params['output'] as $outputType ) { + // The class may be specified as either the full class name (for + // example, 'ProfilerOutputUdp') or (for backward compatibility) + // the trailing portion of the class name (for example, 'udp'). + $outputClass = strpos( $outputType, 'ProfilerOutput' ) === false + ? 'ProfilerOutput' . ucfirst( $outputType ) + : $outputType; + if ( !class_exists( $outputClass ) ) { + throw new MWException( "'$outputType' is an invalid output type" ); + } + $outputInstance = new $outputClass( $this, $this->params ); + if ( $outputInstance->canUse() ) { + $outputs[] = $outputInstance; + } + } + return $outputs; + } + + /** + * Log the data to some store or even the page output + * * @since 1.25 */ public function logData() { - $output = isset( $this->params['output'] ) ? $this->params['output'] : null; + $request = $this->getContext()->getRequest(); - if ( !$output || $this instanceof ProfilerStub ) { - // return early when no output classes defined or we're a stub + $timeElapsed = $request->getElapsedTime(); + $timeElapsedThreshold = $this->params['threshold']; + if ( $timeElapsed <= $timeElapsedThreshold ) { return; } - if ( !is_array( $output ) ) { - $output = array( $output ); + $outputs = $this->getOutputs(); + if ( !$outputs ) { + return; } - foreach ( $output as $outType ) { - if ( !isset( self::$outputTypes[$outType] ) ) { - throw new MWException( "'$outType' is an invalid output type" ); - } - $class = self::$outputTypes[$outType]; - - /** @var ProfilerOutput $profileOut */ - $profileOut = new $class( $this, $this->params ); - if ( $profileOut->canUse() ) { - $profileOut->log( $this->getFunctionStats() ); - } + $stats = $this->getFunctionStats(); + foreach ( $outputs as $output ) { + $output->log( $stats ); } }