MediaWiki  REL1_23
ProfilerMwprof.php
Go to the documentation of this file.
00001 <?php
00035 class ProfilerMwprof extends Profiler {
00036 
00037     // Message types
00038 
00039     const TYPE_SINGLE = 1;
00040     const TYPE_RUNNING = 2;
00041 
00051     public function isPersistent() {
00052         return true;
00053     }
00054 
00063     public function profileIn( $inName ) {
00064         $this->mWorkStack[] = array( $inName, count( $this->mWorkStack ),
00065             $this->getTime(), $this->getTime( 'cpu' ) );
00066     }
00067 
00075     public function getFunctionReport() {
00076         return '';
00077     }
00078 
00087     public function profileOut( $outName ) {
00088         list( $inName, $inCount, $inWall, $inCpu ) = array_pop( $this->mWorkStack );
00089 
00090         // Check for unbalanced profileIn / profileOut calls.
00091         // Bad entries are logged but not sent.
00092         if ( $inName !== $outName ) {
00093             $this->debugGroup( 'ProfilerUnbalanced', json_encode( array( $inName, $outName ) ) );
00094             return;
00095         }
00096 
00097         $elapsedCpu = $this->getTime( 'cpu' ) - $inCpu;
00098         $elapsedWall = $this->getTime() - $inWall;
00099         $this->updateEntry( $outName, $elapsedCpu, $elapsedWall );
00100         $this->updateTrxProfiling( $outName, $elapsedWall );
00101     }
00102 
00110     public function updateEntry( $name, $elapsedCpu, $elapsedWall ) {
00111         // If this is the first measurement for this entry, store plain values.
00112         // Many profiled functions will only be called once per request.
00113         if ( !isset( $this->mCollated[$name] ) ) {
00114             $this->mCollated[$name] = array(
00115                 'cpu'   => $elapsedCpu,
00116                 'wall'  => $elapsedWall,
00117                 'count' => 1,
00118             );
00119             return;
00120         }
00121 
00122         $entry = &$this->mCollated[$name];
00123 
00124         // If it's the second measurement, convert the plain values to
00125         // RunningStat instances, so we can push the incoming values on top.
00126         if ( $entry['count'] === 1 ) {
00127             $cpu = new RunningStat();
00128             $cpu->push( $entry['cpu'] );
00129             $entry['cpu'] = $cpu;
00130 
00131             $wall = new RunningStat();
00132             $wall->push( $entry['wall'] );
00133             $entry['wall'] = $wall;
00134         }
00135 
00136         $entry['count']++;
00137         $entry['cpu']->push( $elapsedCpu );
00138         $entry['wall']->push( $elapsedWall );
00139     }
00140 
00149     public function logData() {
00150         global $wgUDPProfilerHost, $wgUDPProfilerPort;
00151 
00152         $this->close();
00153 
00154         $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
00155         socket_connect( $sock, $wgUDPProfilerHost, $wgUDPProfilerPort );
00156         $bufferLength = 0;
00157         $buffer = '';
00158         foreach ( $this->mCollated as $name => $entry ) {
00159             $count = $entry['count'];
00160             $cpu = $entry['cpu'];
00161             $wall = $entry['wall'];
00162 
00163             if ( $count === 1 ) {
00164                 $data = array( self::TYPE_SINGLE, $name, $cpu, $wall );
00165             } else {
00166                 $data = array( self::TYPE_RUNNING, $name, $count,
00167                     $cpu->m1, $cpu->m2, $cpu->min, $cpu->max,
00168                     $wall->m1, $wall->m2, $wall->min, $wall->max );
00169             }
00170 
00171             $encoded = MWMessagePack::pack( $data );
00172             $length = strlen( $encoded );
00173 
00174             // If adding this entry would cause the size of the buffer to
00175             // exceed the standard ethernet MTU size less the UDP header,
00176             // send all pending data and reset the buffer. Otherwise, continue
00177             // accumulating entries into the current buffer.
00178             if ( $length + $bufferLength > 1450 ) {
00179                 socket_send( $sock, $buffer, $bufferLength, 0 );
00180                 $buffer = '';
00181                 $bufferLength = 0;
00182             }
00183             $buffer .= $encoded;
00184             $bufferLength += $length;
00185         }
00186         if ( $bufferLength !== 0 ) {
00187             socket_send( $sock, $buffer, $bufferLength, 0 );
00188         }
00189     }
00190 }