MediaWiki REL1_37
Profiler.php
Go to the documentation of this file.
1<?php
22use Psr\Log\LoggerInterface;
24use Wikimedia\ScopedCallback;
25
36abstract class Profiler {
38 protected $profileID = false;
40 protected $params = [];
42 protected $context = null;
44 protected $trxProfiler;
46 protected $logger;
48 private $allowOutput = false;
49
51 private static $instance = null;
52
56 public function __construct( array $params ) {
57 if ( isset( $params['profileID'] ) ) {
58 $this->profileID = $params['profileID'];
59 }
60 $this->params = $params;
61 $this->trxProfiler = new TransactionProfiler();
62 $this->logger = LoggerFactory::getInstance( 'profiler' );
63 }
64
69 final public static function instance() {
70 if ( self::$instance === null ) {
71 global $wgProfiler;
72
74 'class' => ProfilerStub::class,
75 'sampling' => 1,
76 'threshold' => 0.0,
77 'output' => [],
78 ];
79
80 $inSample = mt_rand( 0, $params['sampling'] - 1 ) === 0;
81 // wfIsCLI() is not available yet
82 if ( PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg' || !$inSample ) {
83 $params['class'] = ProfilerStub::class;
84 }
85
86 if ( !is_array( $params['output'] ) ) {
87 $params['output'] = [ $params['output'] ];
88 }
89
90 self::$instance = new $params['class']( $params );
91 }
92 return self::$instance;
93 }
94
102 final public static function replaceStubInstance( Profiler $profiler ) {
103 if ( self::$instance && !( self::$instance instanceof ProfilerStub ) ) {
104 throw new MWException( 'Could not replace non-stub profiler instance.' );
105 } else {
106 self::$instance = $profiler;
107 }
108 }
109
113 public function setProfileID( $id ) {
114 $this->profileID = $id;
115 }
116
120 public function getProfileID() {
121 if ( $this->profileID === false ) {
122 return WikiMap::getCurrentWikiDbDomain()->getId();
123 } else {
124 return $this->profileID;
125 }
126 }
127
134 public function setContext( $context ) {
135 $this->context = $context;
136 }
137
144 public function getContext() {
145 if ( $this->context ) {
146 return $this->context;
147 } else {
148 $this->logger->warning( __METHOD__ . " called before setContext, " .
149 "fallback to RequestContext::getMain()." );
150 return RequestContext::getMain();
151 }
152 }
153
154 public function profileIn( $functionname ) {
155 wfDeprecated( __METHOD__, '1.33' );
156 }
157
158 public function profileOut( $functionname ) {
159 wfDeprecated( __METHOD__, '1.33' );
160 }
161
170 abstract public function scopedProfileIn( $section );
171
175 public function scopedProfileOut( SectionProfileCallback &$section = null ) {
176 $section = null;
177 }
178
183 public function getTransactionProfiler() {
184 return $this->trxProfiler;
185 }
186
190 abstract public function close();
191
199 private function getOutputs() {
200 $outputs = [];
201 foreach ( $this->params['output'] as $outputType ) {
202 // The class may be specified as either the full class name (for
203 // example, 'ProfilerOutputStats') or (for backward compatibility)
204 // the trailing portion of the class name (for example, 'stats').
205 $outputClass = strpos( $outputType, 'ProfilerOutput' ) === false
206 ? 'ProfilerOutput' . ucfirst( $outputType )
207 : $outputType;
208 if ( !class_exists( $outputClass ) ) {
209 throw new MWException( "'$outputType' is an invalid output type" );
210 }
211 $outputInstance = new $outputClass( $this, $this->params );
212 if ( $outputInstance->canUse() ) {
213 $outputs[] = $outputInstance;
214 }
215 }
216 return $outputs;
217 }
218
224 public function logData() {
225 $request = $this->getContext()->getRequest();
226
227 $timeElapsed = $request->getElapsedTime();
228 $timeElapsedThreshold = $this->params['threshold'];
229 if ( $timeElapsed <= $timeElapsedThreshold ) {
230 return;
231 }
232
233 $outputs = [];
234 foreach ( $this->getOutputs() as $output ) {
235 if ( !$output->logsToOutput() ) {
236 $outputs[] = $output;
237 }
238 }
239
240 if ( $outputs ) {
241 $stats = $this->getFunctionStats();
242 foreach ( $outputs as $output ) {
243 $output->log( $stats );
244 }
245 }
246 }
247
254 public function logDataPageOutputOnly() {
255 if ( !$this->allowOutput ) {
256 return;
257 }
258
259 $outputs = [];
260 foreach ( $this->getOutputs() as $output ) {
261 if ( $output->logsToOutput() ) {
262 $outputs[] = $output;
263 }
264 }
265
266 if ( $outputs ) {
267 $stats = $this->getFunctionStats();
268 foreach ( $outputs as $output ) {
269 $output->log( $stats );
270 }
271 }
272 }
273
283 public function getContentType() {
284 if ( $this->allowOutput ) {
285 foreach ( headers_list() as $header ) {
286 if ( preg_match( '#^content-type: (\w+/\w+);?#i', $header, $m ) ) {
287 return $m[1];
288 }
289 }
290 }
291 return null;
292 }
293
299 public function setAllowOutput() {
300 $this->allowOutput = true;
301 }
302
309 public function getAllowOutput() {
310 return $this->allowOutput;
311 }
312
339 abstract public function getFunctionStats();
340
346 abstract public function getOutput();
347}
$wgProfiler
Profiler configuration.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
getContext()
MediaWiki exception.
PSR-3 logger instance factory.
Stub profiler that does nothing.
Profiler base class that defines the interface and some shared functionality.
Definition Profiler.php:36
setAllowOutput()
Enable appending profiles to standard output.
Definition Profiler.php:299
static replaceStubInstance(Profiler $profiler)
Replace the current profiler with $profiler if no non-stub profiler is set.
Definition Profiler.php:102
setProfileID( $id)
Definition Profiler.php:113
string bool $profileID
Profiler ID for bucketing data.
Definition Profiler.php:38
static Profiler $instance
Definition Profiler.php:51
getTransactionProfiler()
Definition Profiler.php:183
setContext( $context)
Sets the context for this Profiler.
Definition Profiler.php:134
IContextSource $context
Current request context.
Definition Profiler.php:42
getOutputs()
Get all usable outputs.
Definition Profiler.php:199
close()
Close opened profiling sections.
logData()
Log the data to the backing store for all ProfilerOutput instances that have one.
Definition Profiler.php:224
TransactionProfiler $trxProfiler
Definition Profiler.php:44
__construct(array $params)
Definition Profiler.php:56
profileOut( $functionname)
Definition Profiler.php:158
logDataPageOutputOnly()
Log the data to the script/request output for all ProfilerOutput instances that do so.
Definition Profiler.php:254
getOutput()
Returns a profiling output to be stored in debug file.
static instance()
Singleton.
Definition Profiler.php:69
getContentType()
Get the Content-Type for deciding how to format appended profile output.
Definition Profiler.php:283
getFunctionStats()
Get the aggregated inclusive profiling data for each method.
getProfileID()
Definition Profiler.php:120
scopedProfileIn( $section)
Mark the start of a custom profiling frame (e.g.
getAllowOutput()
Whether appending profiles is allowed.
Definition Profiler.php:309
scopedProfileOut(SectionProfileCallback &$section=null)
Definition Profiler.php:175
bool $allowOutput
Definition Profiler.php:48
LoggerInterface $logger
Definition Profiler.php:46
array $params
All of the params passed from $wgProfiler.
Definition Profiler.php:40
profileIn( $functionname)
Definition Profiler.php:154
getContext()
Gets the context for this Profiler.
Definition Profiler.php:144
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.
$header