summaryrefslogtreecommitdiff
path: root/includes/profiler/ProfilerMwprof.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/profiler/ProfilerMwprof.php')
-rw-r--r--includes/profiler/ProfilerMwprof.php256
1 files changed, 0 insertions, 256 deletions
diff --git a/includes/profiler/ProfilerMwprof.php b/includes/profiler/ProfilerMwprof.php
deleted file mode 100644
index af3c7741..00000000
--- a/includes/profiler/ProfilerMwprof.php
+++ /dev/null
@@ -1,256 +0,0 @@
-<?php
-/**
- * Profiler class for Mwprof.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @file
- * @ingroup Profiler
- */
-
-/**
- * Profiler class for Mwprof.
- *
- * Mwprof is a high-performance MediaWiki profiling data collector, designed to
- * collect profiling data from multiple hosts running in tandem. This class
- * serializes profiling samples into MessagePack arrays and sends them to an
- * Mwprof instance via UDP.
- *
- * @see https://github.com/wikimedia/operations-software-mwprof
- * @since 1.23
- */
-class ProfilerMwprof extends Profiler {
- /** @var array Queue of open profile calls with start data */
- protected $mWorkStack = array();
-
- /** @var array Map of (function name => aggregate data array) */
- protected $mCollated = array();
- /** @var array Cache of a standard broken collation entry */
- protected $mErrorEntry;
-
- // Message types
- const TYPE_SINGLE = 1;
- const TYPE_RUNNING = 2;
-
- public function isStub() {
- return false;
- }
-
- public function isPersistent() {
- return true;
- }
-
- /**
- * Start a profiling section.
- *
- * Marks the beginning of the function or code-block that should be time
- * and logged under some specific name.
- *
- * @param string $inName Section to start
- */
- public function profileIn( $inName ) {
- $this->mWorkStack[] = array( $inName, count( $this->mWorkStack ),
- $this->getTime(), $this->getTime( 'cpu' ), 0 );
- }
-
- /**
- * Close a profiling section.
- *
- * Marks the end of the function or code-block that should be timed and
- * logged under some specific name.
- *
- * @param string $outName Section to close
- */
- public function profileOut( $outName ) {
- list( $inName, $inCount, $inWall, $inCpu ) = array_pop( $this->mWorkStack );
-
- // Check for unbalanced profileIn / profileOut calls.
- // Bad entries are logged but not sent.
- if ( $inName !== $outName ) {
- $this->debugGroup( 'ProfilerUnbalanced', json_encode( array( $inName, $outName ) ) );
- return;
- }
-
- $elapsedCpu = $this->getTime( 'cpu' ) - $inCpu;
- $elapsedWall = $this->getTime() - $inWall;
- $this->updateRunningEntry( $outName, $elapsedCpu, $elapsedWall );
- $this->trxProfiler->recordFunctionCompletion( $outName, $elapsedWall );
- }
-
- /**
- * Update an entry with timing data.
- *
- * @param string $name Section name
- * @param float $elapsedCpu Elapsed CPU time
- * @param float $elapsedWall Elapsed wall-clock time
- */
- public function updateRunningEntry( $name, $elapsedCpu, $elapsedWall ) {
- // If this is the first measurement for this entry, store plain values.
- // Many profiled functions will only be called once per request.
- if ( !isset( $this->mCollated[$name] ) ) {
- $this->mCollated[$name] = array(
- 'cpu' => $elapsedCpu,
- 'wall' => $elapsedWall,
- 'count' => 1,
- );
- return;
- }
-
- $entry = &$this->mCollated[$name];
-
- // If it's the second measurement, convert the plain values to
- // RunningStat instances, so we can push the incoming values on top.
- if ( $entry['count'] === 1 ) {
- $cpu = new RunningStat();
- $cpu->push( $entry['cpu'] );
- $entry['cpu'] = $cpu;
-
- $wall = new RunningStat();
- $wall->push( $entry['wall'] );
- $entry['wall'] = $wall;
- }
-
- $entry['count']++;
- $entry['cpu']->push( $elapsedCpu );
- $entry['wall']->push( $elapsedWall );
- }
-
- /**
- * @return array
- */
- public function getRawData() {
- // This method is called before shutdown in the footer method on Skins.
- // If some outer methods have not yet called wfProfileOut(), work around
- // that by clearing anything in the work stack to just the "-total" entry.
- if ( count( $this->mWorkStack ) > 1 ) {
- $oldWorkStack = $this->mWorkStack;
- $this->mWorkStack = array( $this->mWorkStack[0] ); // just the "-total" one
- } else {
- $oldWorkStack = null;
- }
- $this->close();
- // If this trick is used, then the old work stack is swapped back afterwards.
- // This means that logData() will still make use of all the method data since
- // the missing wfProfileOut() calls should be made by the time it is called.
- if ( $oldWorkStack ) {
- $this->mWorkStack = $oldWorkStack;
- }
-
- $totalWall = 0.0;
- $profile = array();
- foreach ( $this->mCollated as $fname => $data ) {
- if ( $data['count'] == 1 ) {
- $profile[] = array(
- 'name' => $fname,
- 'calls' => $data['count'],
- 'elapsed' => $data['wall'] * 1000,
- 'memory' => 0, // not supported
- 'min' => $data['wall'] * 1000,
- 'max' => $data['wall'] * 1000,
- 'overhead' => 0, // not supported
- 'periods' => array() // not supported
- );
- $totalWall += $data['wall'];
- } else {
- $profile[] = array(
- 'name' => $fname,
- 'calls' => $data['count'],
- 'elapsed' => $data['wall']->n * $data['wall']->getMean() * 1000,
- 'memory' => 0, // not supported
- 'min' => $data['wall']->min * 1000,
- 'max' => $data['wall']->max * 1000,
- 'overhead' => 0, // not supported
- 'periods' => array() // not supported
- );
- $totalWall += $data['wall']->n * $data['wall']->getMean();
- }
- }
- $totalWall = $totalWall * 1000;
-
- foreach ( $profile as &$item ) {
- $item['percent'] = $totalWall ? 100 * $item['elapsed'] / $totalWall : 0;
- }
-
- return $profile;
- }
-
- /**
- * Serialize profiling data and send to a profiling data aggregator.
- *
- * Individual entries are represented as arrays and then encoded using
- * MessagePack, an efficient binary data-interchange format. Encoded
- * entries are accumulated into a buffer and sent in batch via UDP to the
- * profiling data aggregator.
- */
- public function logData() {
- global $wgUDPProfilerHost, $wgUDPProfilerPort;
-
- $this->close();
-
- if ( !function_exists( 'socket_create' ) ) {
- return; // avoid fatal
- }
-
- $sock = socket_create( AF_INET, SOCK_DGRAM, SOL_UDP );
- socket_connect( $sock, $wgUDPProfilerHost, $wgUDPProfilerPort );
- $bufferLength = 0;
- $buffer = '';
- foreach ( $this->mCollated as $name => $entry ) {
- $count = $entry['count'];
- $cpu = $entry['cpu'];
- $wall = $entry['wall'];
-
- if ( $count === 1 ) {
- $data = array( self::TYPE_SINGLE, $name, $cpu, $wall );
- } else {
- $data = array( self::TYPE_RUNNING, $name, $count,
- $cpu->m1, $cpu->m2, $cpu->min, $cpu->max,
- $wall->m1, $wall->m2, $wall->min, $wall->max );
- }
-
- $encoded = MWMessagePack::pack( $data );
- $length = strlen( $encoded );
-
- // If adding this entry would cause the size of the buffer to
- // exceed the standard ethernet MTU size less the UDP header,
- // send all pending data and reset the buffer. Otherwise, continue
- // accumulating entries into the current buffer.
- if ( $length + $bufferLength > 1450 ) {
- socket_send( $sock, $buffer, $bufferLength, 0 );
- $buffer = '';
- $bufferLength = 0;
- }
- $buffer .= $encoded;
- $bufferLength += $length;
- }
- if ( $bufferLength !== 0 ) {
- socket_send( $sock, $buffer, $bufferLength, 0 );
- }
- }
-
- /**
- * Close opened profiling sections
- */
- public function close() {
- while ( count( $this->mWorkStack ) ) {
- $this->profileOut( 'close' );
- }
- }
-
- public function getOutput() {
- return ''; // no report
- }
-}