From 750e4eb9d9517da68a4df08bf50a9a360dafeb05 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 3 Mar 2015 15:17:02 -0800 Subject: [PATCH] Allow dumping raw xhprof data for consumption by xhprof GUI Change-Id: Iab90cef1c61b92ffc6d46a6bc93a03cf7bc2adb9 --- StartProfiler.sample | 5 +- autoload.php | 1 + includes/profiler/Profiler.php | 8 ++- includes/profiler/ProfilerXhprof.php | 8 +++ .../profiler/output/ProfilerOutputDump.php | 51 +++++++++++++++++++ 5 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 includes/profiler/output/ProfilerOutputDump.php diff --git a/StartProfiler.sample b/StartProfiler.sample index 4721a9dde3..6681b870cf 100644 --- a/StartProfiler.sample +++ b/StartProfiler.sample @@ -6,7 +6,7 @@ * * For output, add: * $wgProfiler['output'] = array( 'text' ); - * 'text' can be one (or more) of 'text' 'udp' or 'db' + * 'text' can be one (or more) of 'text' 'udp' 'db' or 'dump' * 'db' requires creating the profiling table, see patch-profiling.sql * * The 'text' output will be added to the output page in a comment approriate @@ -18,6 +18,9 @@ * The 'db' output expects a database table that can be created by applying * maintenance/archives/patch-profiling.sql to your database. * + * The 'dump' output expects a $wgProfiler['outputDir'] telling it where to + * write dump files. The files produced are compatible with the XHProf gui. + * * For a rudimentary sampling profiler: * $wgProfiler['class'] = 'ProfilerXhprof'; * $wgProfiler['output'] = array( 'db' ); diff --git a/autoload.php b/autoload.php index dbc47ab879..998deb92b7 100644 --- a/autoload.php +++ b/autoload.php @@ -907,6 +907,7 @@ $wgAutoloadLocalClasses = array( 'Profiler' => __DIR__ . '/includes/profiler/Profiler.php', 'ProfilerOutput' => __DIR__ . '/includes/profiler/output/ProfilerOutput.php', 'ProfilerOutputDb' => __DIR__ . '/includes/profiler/output/ProfilerOutputDb.php', + 'ProfilerOutputDump' => __DIR__ . '/includes/profiler/output/ProfilerOutputDump.php', 'ProfilerOutputText' => __DIR__ . '/includes/profiler/output/ProfilerOutputText.php', 'ProfilerOutputUdp' => __DIR__ . '/includes/profiler/output/ProfilerOutputUdp.php', 'ProfilerSectionOnly' => __DIR__ . '/includes/profiler/ProfilerSectionOnly.php', diff --git a/includes/profiler/Profiler.php b/includes/profiler/Profiler.php index 4b7420699f..69470fd95f 100644 --- a/includes/profiler/Profiler.php +++ b/includes/profiler/Profiler.php @@ -46,6 +46,7 @@ abstract class Profiler { 'db' => 'ProfilerOutputDb', 'text' => 'ProfilerOutputText', 'udp' => 'ProfilerOutputUdp', + 'dump' => 'ProfilerOutputDump', ); /** @var Profiler */ @@ -167,7 +168,7 @@ abstract class Profiler { if ( !is_array( $output ) ) { $output = array( $output ); } - + $stats = null; foreach ( $output as $outType ) { if ( !isset( self::$outputTypes[$outType] ) ) { throw new MWException( "'$outType' is an invalid output type" ); @@ -177,7 +178,10 @@ abstract class Profiler { /** @var ProfilerOutput $profileOut */ $profileOut = new $class( $this, $this->params ); if ( $profileOut->canUse() ) { - $profileOut->log( $this->getFunctionStats() ); + if ( is_null( $stats ) ) { + $stats = $this->getFunctionStats(); + } + $profileOut->log( $stats ); } } } diff --git a/includes/profiler/ProfilerXhprof.php b/includes/profiler/ProfilerXhprof.php index 7a504979bc..f36cdc1a89 100644 --- a/includes/profiler/ProfilerXhprof.php +++ b/includes/profiler/ProfilerXhprof.php @@ -183,4 +183,12 @@ class ProfilerXhprof extends Profiler { } return implode( "\n", $out ); } + + /** + * Retrieve raw data from xhprof + * @return array + */ + public function getRawData() { + return $this->xhprof->getRawData(); + } } diff --git a/includes/profiler/output/ProfilerOutputDump.php b/includes/profiler/output/ProfilerOutputDump.php new file mode 100644 index 0000000000..bf4b85c2b8 --- /dev/null +++ b/includes/profiler/output/ProfilerOutputDump.php @@ -0,0 +1,51 @@ +params['outputDir'] ) ) { + return false; + } + return true; + } + + public function log( array $stats ) { + $data = $this->collector->getRawData(); + $filename = sprintf( "%s/%s.%s%s", $this->params['outputDir'], uniqid(), $this->collector->getProfileID(), $this->suffix ); + file_put_contents( $filename, serialize( $data ) ); + } +} -- 2.20.1