MediaWiki fundraising/REL1_35
Profiler.php
Go to the documentation of this file.
1<?php
21use Wikimedia\ScopedCallback;
22
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 ) {
65 global $wgProfiler;
66
68 'class' => ProfilerStub::class,
69 'sampling' => 1,
70 'threshold' => 0.0,
71 'output' => [],
72 ];
73
74 $inSample = mt_rand( 0, $params['sampling'] - 1 ) === 0;
75 // wfIsCLI() is not available yet
76 if ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' || !$inSample ) {
77 $params['class'] = ProfilerStub::class;
78 }
79
80 if ( !is_array( $params['output'] ) ) {
81 $params['output'] = [ $params['output'] ];
82 }
83
84 self::$instance = new $params['class']( $params );
85 }
86 return self::$instance;
87 }
88
96 final public static function replaceStubInstance( Profiler $profiler ) {
97 if ( self::$instance && !( self::$instance instanceof ProfilerStub ) ) {
98 throw new MWException( 'Could not replace non-stub profiler instance.' );
99 } else {
100 self::$instance = $profiler;
101 }
102 }
103
107 public function setProfileID( $id ) {
108 $this->profileID = $id;
109 }
110
114 public function getProfileID() {
115 if ( $this->profileID === false ) {
116 return WikiMap::getCurrentWikiDbDomain()->getId();
117 } else {
118 return $this->profileID;
119 }
120 }
121
128 public function setContext( $context ) {
129 $this->context = $context;
130 }
131
138 public function getContext() {
139 if ( $this->context ) {
140 return $this->context;
141 } else {
142 wfDebug( __METHOD__ . " called and \$context is null. " .
143 "Return RequestContext::getMain(); for sanity" );
144 return RequestContext::getMain();
145 }
146 }
147
148 public function profileIn( $functionname ) {
149 wfDeprecated( __METHOD__, '1.33' );
150 }
151
152 public function profileOut( $functionname ) {
153 wfDeprecated( __METHOD__, '1.33' );
154 }
155
164 abstract public function scopedProfileIn( $section );
165
169 public function scopedProfileOut( SectionProfileCallback &$section = null ) {
170 $section = null;
171 }
172
177 public function getTransactionProfiler() {
178 return $this->trxProfiler;
179 }
180
184 abstract public function close();
185
193 private function getOutputs() {
194 $outputs = [];
195 foreach ( $this->params['output'] as $outputType ) {
196 // The class may be specified as either the full class name (for
197 // example, 'ProfilerOutputStats') or (for backward compatibility)
198 // the trailing portion of the class name (for example, 'stats').
199 $outputClass = strpos( $outputType, 'ProfilerOutput' ) === false
200 ? 'ProfilerOutput' . ucfirst( $outputType )
201 : $outputType;
202 if ( !class_exists( $outputClass ) ) {
203 throw new MWException( "'$outputType' is an invalid output type" );
204 }
205 $outputInstance = new $outputClass( $this, $this->params );
206 if ( $outputInstance->canUse() ) {
207 $outputs[] = $outputInstance;
208 }
209 }
210 return $outputs;
211 }
212
218 public function logData() {
219 $request = $this->getContext()->getRequest();
220
221 $timeElapsed = $request->getElapsedTime();
222 $timeElapsedThreshold = $this->params['threshold'];
223 if ( $timeElapsed <= $timeElapsedThreshold ) {
224 return;
225 }
226
227 $outputs = [];
228 foreach ( $this->getOutputs() as $output ) {
229 if ( !$output->logsToOutput() ) {
230 $outputs[] = $output;
231 }
232 }
233
234 if ( $outputs ) {
235 $stats = $this->getFunctionStats();
236 foreach ( $outputs as $output ) {
237 $output->log( $stats );
238 }
239 }
240 }
241
248 public function logDataPageOutputOnly() {
249 if ( !$this->allowOutput ) {
250 return;
251 }
252
253 $outputs = [];
254 foreach ( $this->getOutputs() as $output ) {
255 if ( $output->logsToOutput() ) {
256 $outputs[] = $output;
257 }
258 }
259
260 if ( $outputs ) {
261 $stats = $this->getFunctionStats();
262 foreach ( $outputs as $output ) {
263 $output->log( $stats );
264 }
265 }
266 }
267
277 public function getContentType() {
278 if ( $this->allowOutput ) {
279 foreach ( headers_list() as $header ) {
280 if ( preg_match( '#^content-type: (\w+/\w+);?#i', $header, $m ) ) {
281 return $m[1];
282 }
283 }
284 }
285 return null;
286 }
287
294 public function setTemplated( $t ) {
295 wfDeprecated( __METHOD__, '1.34' );
296 $this->allowOutput = ( $t === true );
297 }
298
305 public function getTemplated() {
306 wfDeprecated( __METHOD__, '1.34' );
307 return $this->getAllowOutput();
308 }
309
315 public function setAllowOutput() {
316 $this->allowOutput = true;
317 }
318
325 public function getAllowOutput() {
326 return $this->allowOutput;
327 }
328
355 abstract public function getFunctionStats();
356
362 abstract public function getOutput();
363}
$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)
Logs a warning that $function is deprecated.
getContext()
MediaWiki exception.
Stub profiler that does nothing.
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:33
setAllowOutput()
Enable appending profiles to standard output.
Definition Profiler.php:315
static replaceStubInstance(Profiler $profiler)
Replace the current profiler with $profiler if no non-stub profiler is set.
Definition Profiler.php:96
setProfileID( $id)
Definition Profiler.php:107
string bool $profileID
Profiler ID for bucketing data.
Definition Profiler.php:35
static Profiler $instance
Definition Profiler.php:46
getTransactionProfiler()
Definition Profiler.php:177
setContext( $context)
Sets the context for this Profiler.
Definition Profiler.php:128
setTemplated( $t)
Mark this call as templated or not.
Definition Profiler.php:294
IContextSource $context
Current request context.
Definition Profiler.php:39
getOutputs()
Get all usable outputs.
Definition Profiler.php:193
close()
Close opened profiling sections.
logData()
Log the data to the backing store for all ProfilerOutput instances that have one.
Definition Profiler.php:218
TransactionProfiler $trxProfiler
Definition Profiler.php:41
__construct(array $params)
Definition Profiler.php:51
profileOut( $functionname)
Definition Profiler.php:152
logDataPageOutputOnly()
Log the data to the script/request output for all ProfilerOutput instances that do so.
Definition Profiler.php:248
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:277
getFunctionStats()
Get the aggregated inclusive profiling data for each method.
getProfileID()
Definition Profiler.php:114
scopedProfileIn( $section)
Mark the start of a custom profiling frame (e.g.
getTemplated()
Was this call as templated or not.
Definition Profiler.php:305
getAllowOutput()
Whether appending profiles is allowed.
Definition Profiler.php:325
scopedProfileOut(SectionProfileCallback &$section=null)
Definition Profiler.php:169
bool $allowOutput
Definition Profiler.php:43
array $params
All of the params passed from $wgProfiler.
Definition Profiler.php:37
profileIn( $functionname)
Definition Profiler.php:148
getContext()
Gets the context for this Profiler.
Definition Profiler.php:138
Subclass ScopedCallback to avoid call_user_func_array(), which is slow.
Detect high-contention DB queries via profiling calls.
Interface for objects which can provide a MediaWiki context on request.
return true
Definition router.php:92
$header