Added custom frame support to Profiler
authorAaron Schulz <aschulz@wikimedia.org>
Sat, 22 Nov 2014 01:13:27 +0000 (17:13 -0800)
committerBryan Davis <bd808@wikimedia.org>
Tue, 25 Nov 2014 21:52:21 +0000 (14:52 -0700)
* Made use of it in the DatabaseBase classes
* For the xhprof class, this only works in HHVM for now

Change-Id: I95d7cc128d4a770328fbdd2b546972d3fc2e2e8a

includes/db/Database.php
includes/profiler/Profiler.php
includes/profiler/ProfilerStandard.php
includes/profiler/ProfilerStub.php
includes/profiler/ProfilerXhprof.php

index fc2451e..fc13eeb 100644 (file)
@@ -962,7 +962,8 @@ abstract class DatabaseBase implements IDatabase {
                $totalProf = '';
                $isMaster = !is_null( $this->getLBInfo( 'master' ) );
 
-               if ( !Profiler::instance()->isStub() ) {
+               $profiler = Profiler::instance();
+               if ( !$profiler->isStub() ) {
                        # generalizeSQL will probably cut down the query to reasonable
                        # logging size most of the time. The substr is really just a sanity check.
                        if ( $isMaster ) {
@@ -975,8 +976,8 @@ abstract class DatabaseBase implements IDatabase {
                        # Include query transaction state
                        $queryProf .= $this->mTrxShortId ? " [TRX#{$this->mTrxShortId}]" : "";
 
-                       wfProfileIn( $totalProf );
-                       wfProfileIn( $queryProf );
+                       $totalProfSection = $profiler->scopedProfileIn( $totalProf );
+                       $queryProfSection = $profiler->scopedProfileIn( $queryProf );
                }
 
                if ( $this->debug() ) {
@@ -1059,11 +1060,6 @@ abstract class DatabaseBase implements IDatabase {
                        $this->reportQueryError( $this->lastError(), $this->lastErrno(), $sql, $fname, $tempIgnore );
                }
 
-               if ( !Profiler::instance()->isStub() ) {
-                       wfProfileOut( $queryProf );
-                       wfProfileOut( $totalProf );
-               }
-
                return $this->resultObject( $ret );
        }
 
index 2b3b616..9650ff5 100644 (file)
@@ -139,6 +139,23 @@ abstract class Profiler {
         */
        abstract public function profileOut( $functionname );
 
+       /**
+        * Mark the start of a custom profiling frame (e.g. DB queries).
+        * The frame ends when the result of this method falls out of scope.
+        *
+        * @param string $section
+        * @return ScopedCallback|null
+        * @since 1.25
+        */
+       abstract public function scopedProfileIn( $section );
+
+       /**
+        * @param ScopedCallback $section
+        */
+       public function scopedProfileOut( ScopedCallback &$section ) {
+               $section = null;
+       }
+
        /**
         * @return TransactionProfiler
         * @since 1.25
index 15c5cdd..ab5e3ab 100644 (file)
@@ -227,6 +227,15 @@ class ProfilerStandard extends Profiler {
                }
        }
 
+       public function scopedProfileIn( $section ) {
+               $this->profileIn( $section );
+
+               $that = $this;
+               return new ScopedCallback( function() use ( $that, $section ) {
+                       $that->profileOut( $section );
+               } );
+       }
+
        /**
         * Close opened profiling sections
         */
index 510a0a0..6fc74ef 100644 (file)
@@ -37,6 +37,10 @@ class ProfilerStub extends Profiler {
        public function profileOut( $fn ) {
        }
 
+       public function scopedProfileIn( $section ) {
+               return null;
+       }
+
        public function getFunctionStats() {
        }
 
index d67806b..cbd081d 100644 (file)
@@ -122,6 +122,23 @@ class ProfilerXhprof extends Profiler {
        public function profileOut( $functionname ) {
        }
 
+       public function scopedProfileIn( $section ) {
+               static $exists = null;
+               // Only HHVM supports this, not the standard PECL extension
+               if ( $exists === null ) {
+                       $exists = function_exists( 'xhprof_frame_begin' );
+               }
+
+               if ( $exists ) {
+                       xhprof_frame_begin( $section );
+                       return new ScopedCallback( function() use ( $section ) {
+                               xhprof_frame_end( $section );
+                       } );
+               }
+
+               return null;
+       }
+
        /**
         * No-op for xhprof profiling.
         */