Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Support for gzipping files and arbitrary metadata #10

Closed
wants to merge 10 commits into
from
@@ -21,6 +21,8 @@
<li><a href="#sampling_mode">Lightweight Sampling Mode</a>
+<li><a href="#metadata">Including Metadata</a></li>
+
<li><a href="#misc">Additional features</a></li>
<li><a href="#dependencies">Dependencies</a></li>
@@ -764,6 +766,25 @@
<p>[<b>TBD</b>: more detailed documentation on sampling mode.]
+<li><a name="metadata"><h2>Including Metadata</h2></a></li>
+
+<p>It is also possible to include metadata that is associated with a given run.
+For instance you might want to include the URI that was requested, or the
+IP of the remote machine. This is simple to do:
+
+<p><pre><code>
+ //create your metadata array, it will be recurisively turned into a table
+ $metadata = array();
+ $metadata['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
+ $metadata['HTTP_X_FORWARDED_FOR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
+ $metadata['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
+
+ //save the run, note the last param is the metadata from above, it is optional
+ $xhprof_data = xhprof_disable();
+ $xhprof_runs = new XHProfRuns_Default();
+ $XHPROF_WELL_RUN_ID = $xhprof_runs->save_run($xhprof_data, $XHPROF_WELL_PROFILER_NAMESPACE, null, $metadata);
+</code></pre></p>
+
<li><a name="misc"><h2>Additional Features</h2></a></li>
<p>The <code><b>xhprof_lib/utils/xhprof_lib.php</b></code> file contains
@@ -1304,7 +1304,14 @@ function profiler_single_run_report ($url_params,
$run_desc,
$rep_symbol,
$sort,
- $run) {
+ $run,
+ $metadata = null ) {
+
+
+ //display metadata in a table if there is any
+ if ( $metadata ) {
+ dump_table( $metadata, "Run Metadata");
+ }
init_metrics($xhprof_data, $rep_symbol, $sort, false);
@@ -1344,6 +1351,49 @@ function profiler_diff_report($url_params,
$xhprof_data2);
}
+function dump_table($var, $title=false, $level=0)
+{
+ if($level==0)
+ {
+ echo '<table border="1" cellspacing="1" cellpadding="3" class="dump">';
+
+ if($title)
+ echo '<tr>
+ <th colspan="2">'.$title.'</th>
+ </tr>';
+
+ echo '
+ <tr>
+ <th>VAR NAME</th>
+ <th>VALUE</th>
+ </tr>';
+ }
+ else
+ {
+ echo '<tr>
+ <td colspan="2">
+ <table width="100%" border="0" cellspacing="3" cellpadding="3" class="dump_b">
+ </td>
+ </tr>';
+ }
+
+ foreach($var as $i=>$value)
+ {
+ if(is_array($value) or is_object($value))
+ {
+ dump_table($value, false, ($level +1));
+ }
+ else
+ {
+ echo '<tr>
+ <td width="50%" >'.$i.'</th>
+ <td width="50%" >'.$value.'</th>
+ </tr>';
+ }
+ }
+ echo '</table>';
+}
+
/**
* Generate a XHProf Display View given the various URL parameters
@@ -1395,6 +1445,9 @@ function displayXHProfReport($xhprof_runs_impl, $url_params, $source,
$xhprof_data = $xhprof_runs_impl->get_run($runs_array[0],
$source,
$description);
+ $metadata = $xhprof_runs_impl->get_metadata( $runs_array[0],
+ $source );
+
} else {
if (!empty($wts)) {
$wts_array = explode(",", $wts);
@@ -1403,6 +1456,10 @@ function displayXHProfReport($xhprof_runs_impl, $url_params, $source,
}
$data = xhprof_aggregate_runs($xhprof_runs_impl,
$runs_array, $wts_array, $source, false);
+
+ //for now metadata for multiple runs isn't implemented, sorry
+ $metadata = null;
+
$xhprof_data = $data['raw'];
$description = $data['description'];
}
@@ -1413,7 +1470,8 @@ function displayXHProfReport($xhprof_runs_impl, $url_params, $source,
$description,
$symbol,
$sort,
- $run);
+ $run,
+ $metadata);
} else if ($run1 && $run2) { // diff report for two runs
@@ -41,6 +41,14 @@
public function get_run($run_id, $type, &$run_desc);
/**
+ * Returns meta data associated with a given XHPRof run id ($run) of
+ * a given type ($type).
+ *
+ */
+ public function get_metadata($run_id, $type);
+
+
+ /**
* Save XHProf data for a profiler run of specified type
* ($type).
*
@@ -49,10 +57,16 @@ public function get_run($run_id, $type, &$run_desc);
* the implementation of this method must generated a
* unique run id for this saved XHProf run.
*
+ * The Caller may also optionally pass in metadata, which
+ * is an array containing metadata to included ( and displayed )
+ * along with this run.
+ *
* Returns the run id for the saved XHProf run.
*
*/
- public function save_run($xhprof_data, $type, $run_id = null);
+
+ public function save_run($xhprof_data, $type, $run_id = null, $metadata = null );
+
}
@@ -76,11 +90,12 @@ private function gen_run_id($type) {
private function file_name($run_id, $type) {
- $file = "$run_id.$type." . $this->suffix;
+ $file = "$run_id.$type." . $this->suffix . ".gz";
if (!empty($this->dir)) {
- $file = $this->dir . "/" . $file;
+ $file = $this->dir . "/" . $file;
}
+
return $file;
}
@@ -109,35 +124,105 @@ public function __construct($dir = null) {
}
public function get_run($run_id, $type, &$run_desc) {
+
$file_name = $this->file_name($run_id, $type);
if (!file_exists($file_name)) {
- xhprof_error("Could not find file $file_name");
- $run_desc = "Invalid Run Id = $run_id";
- return null;
+
+ //backwards compatibility with non-gziped runs
+ $without_gz = substr( $file_name, 0, -3 );
+ if ( !file_exists($without_gz) ) {
+ xhprof_error("Could not find file $file_name (or $without_gz)");
+ $run_desc = "Invalid Run Id = $run_id";
+ return null;
+ }
+ else {
+ $file_name = $without_gz;
+ }
}
- $contents = file_get_contents($file_name);
+ //backwards compatible support for both gziped or regular runs
+ if ( substr( $file_name, -3, 3 ) == ".gz" ) {
+ $data = gzfile($file_name);
+ }
+ else {
+ $data = file($file_name);
+ }
+
+ $contents = implode($data);
$run_desc = "XHProf Run (Namespace=$type)";
- return unserialize($contents);
+ $unserialized = unserialize($contents);
+
+ //if the unserialized data is an arrray, the data is using the metadata format
+ //we only return the xhprof_data to maintains api compatibility
+ if ( gettype( $unserialized ) == 'array' ) {
+ return $unserialized['xhprof_data'];
+ }
+ else {
+ return $unserialized;
+ }
+ }
+
+ public function get_metadata( $run_id, $type ) {
+
+ $file_name = $this->file_name($run_id, $type);
+
+ if (!file_exists($file_name)) {
+
+ //backwards compatibility with non-gziped runs
+ $without_gz = substr( $file_name, 0, -3 );
+ if ( !file_exists($without_gz) ) {
+ xhprof_error("Could not find file $file_name (or $without_gz)");
+ $run_desc = "Invalid Run Id = $run_id";
+ return null;
+ }
+ else {
+ $file_name = $without_gz;
+ }
+ }
+
+ //backwards compatible support for both gziped or regular runs
+ if ( substr( $file_name, -3, 3 ) == ".gz" ) {
+ $data = gzfile($file_name);
+ }
+ else {
+ $data = file($file_name);
+ }
+
+ $contents = implode($data);
+ $unserialized = unserialize($contents);
+
+ //if the unserialized data is an arrray, the data is using the metadata format
+ //we only return the xhprof_data to maintains api compatibility
+ if ( gettype( $unserialized ) == 'array' ) {
+ return $unserialized['metadata'];
+ }
+ else {
+ return null;
+ }
}
- public function save_run($xhprof_data, $type, $run_id = null) {
+ public function save_run($xhprof_data, $type, $run_id = null, $metadata = null ) {
// Use PHP serialize function to store the XHProf's
// raw profiler data.
- $xhprof_data = serialize($xhprof_data);
+ $all_data = array(
+ "xhprof_data" => $xhprof_data,
+ "metadata" => $metadata,
+ );
+ $all_data = serialize($all_data);
if ($run_id === null) {
$run_id = $this->gen_run_id($type);
}
-
+
$file_name = $this->file_name($run_id, $type);
- $file = fopen($file_name, 'w');
+
+ $file = gzopen($file_name, 'w');
if ($file) {
- fwrite($file, $xhprof_data);
- fclose($file);
+ gzwrite($file, $all_data);
+ gzclose($file);
} else {
xhprof_error("Could not open $file_name\n");
}
@@ -149,7 +234,7 @@ public function save_run($xhprof_data, $type, $run_id = null) {
function list_runs() {
if (is_dir($this->dir)) {
echo "<hr/>Existing runs:\n<ul>\n";
- $files = glob("{$this->dir}/*.{$this->suffix}");
+ $files = glob("{$this->dir}/*.{$this->suffix}*");
usort($files, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));
foreach ($files as $file) {
list($run,$source) = explode('.', basename($file));