MediaWiki REL1_34
Profiler.php
Go to the documentation of this file.
1<?php
24use Wikimedia\ScopedCallback;
26
33abstract class Profiler {
35 protected $profileID = false;
37 protected $params = [];
39 protected $context = null;
41 protected $trxProfiler;
43 private $allowOutput = false;
44
46 private static $instance = null;
47
51 public function __construct( array $params ) {
52 if ( isset( $params['profileID'] ) ) {
53 $this->profileID = $params['profileID'];
54 }
55 $this->params = $params;
56 $this->trxProfiler = new TransactionProfiler();
57 }
58
63 final public static function instance() {
64 if ( self::$instance === null ) {
66
67 $params = [
68 'class' => ProfilerStub::class,
69 'sampling' => 1,
70 'threshold' => $wgProfileLimit,
71 'output' => [],
72 ];
73 if ( is_array( $wgProfiler ) ) {
74 $params = array_merge( $params, $wgProfiler );
75 }
76
77 $inSample = mt_rand( 0, $params['sampling'] - 1 ) === 0;
78 // wfIsCLI() is not available yet
79 if ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' || !$inSample ) {
80 $params['class'] = ProfilerStub::class;
81 }
82
83 if ( !is_array( $params['output'] ) ) {
84 $params['output'] = [ $params['output'] ];
85 }
86
87 self::$instance = new $params['class']( $params );
88 }
89 return self::$instance;
90 }
91
99 final public static function replaceStubInstance( Profiler $profiler ) {
100 if ( self::$instance && !( self::$instance instanceof ProfilerStub ) ) {
101 throw new MWException( 'Could not replace non-stub profiler instance.' );
102 } else {
103 self::$instance = $profiler;
104 }
105 }
106
110 public function setProfileID( $id ) {
111 $this->profileID = $id;
112 }
113
117 public function getProfileID() {
118 if ( $this->profileID === false ) {
119 return WikiMap::getCurrentWikiDbDomain()->getId();
120 } else {
121 return $this->profileID;
122 }
123 }
124
131 public function setContext( $context ) {
132 $this->context = $context;
133 }
134
141 public function getContext() {
142 if ( $this->context ) {
143 return $this->context;
144 } else {
145 wfDebug( __METHOD__ . " called and \$context is null. " .
146 "Return RequestContext::getMain(); for sanity\n" );
147 return RequestContext::getMain();
148 }
149 }
150
151 public function profileIn( $functionname ) {
152 wfDeprecated( __METHOD__, '1.33' );
153 }
154
155 public function profileOut( $functionname ) {
156 wfDeprecated( __METHOD__, '1.33' );
157 }
158
167 abstract public function scopedProfileIn( $section );
168
172 public function scopedProfileOut( SectionProfileCallback &$section = null ) {
173 $section = null;
174 }
175
180 public function getTransactionProfiler() {
181 return $this->trxProfiler;
182 }
183
187 abstract public function close();
188
196 private function getOutputs() {
197 $outputs = [];
198 foreach ( $this->params['output'] as $outputType ) {
199 // The class may be specified as either the full class name (for
200 // example, 'ProfilerOutputStats') or (for backward compatibility)
201 // the trailing portion of the class name (for example, 'stats').
202 $outputClass = strpos( $outputType, 'ProfilerOutput' ) === false
203 ? 'ProfilerOutput' . ucfirst( $outputType )
204 : $outputType;
205 if ( !class_exists( $outputClass ) ) {
206 throw new MWException( "'$outputType' is an invalid output type" );
207 }
208 $outputInstance = new $outputClass( $this, $this->params );
209 if ( $outputInstance->canUse() ) {
210 $outputs[] = $outputInstance;
211 }
212 }
213 return $outputs;
214 }
215
221 public function logData() {
222 $request = $this->getContext()->getRequest();
223
224 $timeElapsed = $request->getElapsedTime();
225 $timeElapsedThreshold = $this->params['threshold'];
226 if ( $timeElapsed <= $timeElapsedThreshold ) {
227 return;
228 }
229
230 $outputs = [];
231 foreach ( $this->getOutputs() as $output ) {
232 if ( !$output->logsToOutput() ) {
233 $outputs[] = $output;
234 }
235 }
236
237 if ( $outputs ) {
238 $stats = $this->getFunctionStats();
239 foreach ( $outputs as $output ) {
240 $output->log( $stats );
241 }
242 }
243 }
244
251 public function logDataPageOutputOnly() {
252 if ( !$this->allowOutput ) {
253 return;
254 }
255
256 $outputs = [];
257 foreach ( $this->getOutputs() as $output ) {
258 if ( $output->logsToOutput() ) {
259 $outputs[] = $output;
260 }
261 }
262
263 if ( $outputs ) {
264 $stats = $this->getFunctionStats();
265 foreach ( $outputs as $output ) {
266 $output->log( $stats );
267 }
268 }
269 }
270
280 public function getContentType() {
281 if ( $this->allowOutput ) {
282 foreach ( headers_list() as $header ) {
283 if ( preg_match( '#^content-type: (\w+/\w+);?#i', $header, $m ) ) {
284 return $m[1];
285 }
286 }
287 }
288 return null;
289 }
290
297 public function setTemplated( $t ) {
298 wfDeprecated( __METHOD__, '1.34' );
299 $this->allowOutput = ( $t === true );
300 }
301
308 public function getTemplated() {
309 wfDeprecated( __METHOD__, '1.34' );
310 return $this->getAllowOutput();
311 }
312
318 public function setAllowOutput() {
319 $this->allowOutput = true;
320 }
321
328 public function getAllowOutput() {
329 return $this->allowOutput;
330 }
331
358 abstract public function getFunctionStats();
359
365 abstract public function getOutput();
366}
$wgProfileLimit
Only record profiling info for pages that took longer than this.
$wgProfiler
Profiler configuration.
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
getContext()
MediaWiki exception.
Stub profiler that does nothing.
Profiler base class that defines the interface and some trivial functionality.
Definition Profiler.php:33
setAllowOutput()
Enable appending profiles to standard output.
Definition Profiler.php:318
static replaceStubInstance(Profiler $profiler)
Replace the current profiler with $profiler if no non-stub profiler is set.
Definition Profiler.php:99
setProfileID( $id)
Definition Profiler.php:110
string bool $profileID
Profiler ID for bucketing data.
Definition Profiler.php:35
static Profiler $instance
Definition Profiler.php:46
getTransactionProfiler()
Definition Profiler.php:180
setContext( $context)
Sets the context for this Profiler.
Definition Profiler.php:131
setTemplated( $t)
Mark this call as templated or not.
Definition Profiler.php:297
getOutputs()
Get all usable outputs.
Definition Profiler.php:196
close()
Close opened profiling sections.
logData()
Log the data to the backing store for all ProfilerOutput instances that have one.
Definition Profiler.php:221
TransactionProfiler $trxProfiler
Definition Profiler.php:41
__construct(array $params)
Definition Profiler.php:51
profileOut( $functionname)
Definition Profiler.php:155
logDataPageOutputOnly()
Log the data to the script/request output for all ProfilerOutput instances that do so.
Definition Profiler.php:251
getOutput()
Returns a profiling output to be stored in debug file.
static instance()
Singleton.
Definition Profiler.php:63
getContentType()
Get the Content-Type for deciding how to format appended profile output.
Definition Profiler.php:280
getFunctionStats()
Get the aggregated inclusive profiling data for each method.
getProfileID()
Definition Profiler.php:117
scopedProfileIn( $section)
Mark the start of a custom profiling frame (e.g.
getTemplated()
Was this call as templated or not.
Definition Profiler.php:308
getAllowOutput()
Whether appending profiles is allowed.
Definition Profiler.php:328
scopedProfileOut(SectionProfileCallback &$section=null)
Definition Profiler.php:172
bool $allowOutput
Definition Profiler.php:43
array $params
All of the params passed from $wgProfiler.
Definition Profiler.php:37
profileIn( $functionname)
Definition Profiler.php:151
getContext()
Gets the context for this Profiler.
Definition Profiler.php:141
Subclass ScopedCallback to avoid call_user_func_array(), which is slow.
Helper class that detects high-contention DB queries via profiling calls.
Interface for objects which can provide a MediaWiki context on request.
$context
Definition load.php:45
return true
Definition router.php:94
$header