- /************************************************************************//**
- * @name Profiling
- * @{
- */
-
- /**
- * Profiling: total module execution time
- */
- private $mTimeIn = 0, $mModuleTime = 0;
- /** @var ScopedCallback */
- private $profile;
- /** @var ScopedCallback */
- private $dbProfile;
-
- /**
- * Get the name of the module as shown in the profiler log
- *
- * @param DatabaseBase|bool $db
- *
- * @return string
- */
- public function getModuleProfileName( $db = false ) {
- if ( $db ) {
- return 'API:' . $this->mModuleName . '-DB';
- }
-
- return 'API:' . $this->mModuleName;
- }
-
- /**
- * Start module profiling
- */
- public function profileIn() {
- if ( $this->mTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called twice without calling profileOut()' );
- }
- $this->mTimeIn = microtime( true );
- $this->profile = Profiler::instance()->scopedProfileIn( $this->getModuleProfileName() );
- }
-
- /**
- * End module profiling
- */
- public function profileOut() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileIn() first' );
- }
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug(
- __METHOD__,
- 'Must be called after database profiling is done with profileDBOut()'
- );
- }
-
- $this->mModuleTime += microtime( true ) - $this->mTimeIn;
- $this->mTimeIn = 0;
- Profiler::instance()->scopedProfileOut( $this->profile );
- }
-
- /**
- * When modules crash, sometimes it is needed to do a profileOut() regardless
- * of the profiling state the module was in. This method does such cleanup.
- */
- public function safeProfileOut() {
- if ( $this->mTimeIn !== 0 ) {
- if ( $this->mDBTimeIn !== 0 ) {
- $this->profileDBOut();
- }
- $this->profileOut();
- }
- }
-
- /**
- * Total time the module was executed
- * @return float
- */
- public function getProfileTime() {
- if ( $this->mTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileOut() first' );
- }
-
- return $this->mModuleTime;
- }
-
- /**
- * Profiling: database execution time
- */
- private $mDBTimeIn = 0, $mDBTime = 0;
-
- /**
- * Start module profiling
- */
- public function profileDBIn() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug(
- __METHOD__,
- 'Must be called while profiling the entire module with profileIn()'
- );
- }
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called twice without calling profileDBOut()' );
- }
- $this->mDBTimeIn = microtime( true );
-
- $this->dbProfile = Profiler::instance()->scopedProfileIn( $this->getModuleProfileName( true ) );
- }
-
- /**
- * End database profiling
- */
- public function profileDBOut() {
- if ( $this->mTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Must be called while profiling ' .
- 'the entire module with profileIn()' );
- }
- if ( $this->mDBTimeIn === 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileDBIn() first' );
- }
-
- $time = microtime( true ) - $this->mDBTimeIn;
- $this->mDBTimeIn = 0;
-
- $this->mDBTime += $time;
- $this->getMain()->mDBTime += $time;
- Profiler::instance()->scopedProfileOut( $this->dbProfile );
- }
-
- /**
- * Total time the module used the database
- * @return float
- */
- public function getProfileDBTime() {
- if ( $this->mDBTimeIn !== 0 ) {
- ApiBase::dieDebug( __METHOD__, 'Called without calling profileDBOut() first' );
- }
-
- return $this->mDBTime;
- }
-
- /**
- * Write logging information for API features to a debug log, for usage
- * analysis.
- * @param string $feature Feature being used.
- */
- protected function logFeatureUsage( $feature ) {
- $request = $this->getRequest();
- $s = '"' . addslashes( $feature ) . '"' .
- ' "' . wfUrlencode( str_replace( ' ', '_', $this->getUser()->getName() ) ) . '"' .
- ' "' . $request->getIP() . '"' .
- ' "' . addslashes( $request->getHeader( 'Referer' ) ) . '"' .
- ' "' . addslashes( $this->getMain()->getUserAgent() ) . '"';
- wfDebugLog( 'api-feature-usage', $s, 'private' );
- }
-
- /**@}*/
-