Permalink
Browse files

MDL-26891 profiling - earlier runs

This allows profiling to be started earlier in the
setup.php execution, by configuring everything in
the config.php file. That way some interesting code
is also profiled, like DB connections, load of config records...

100% compatible with normal profiling and enabled via
special setting $CFG->earlyprofilingenabled

Example (to be put on config.php):

$CFG->earlyprofilingenabled = true;
$CFG->profilingautofrec = 3;
$CFG->profilingincluded = '/*';
$CFG->profilingallowme = true;

(to enable early profiling for 1/3 of any requests while also
allowing to use the PROFILEME PGC)
  • Loading branch information...
1 parent dae6b38 commit c646dd26ea6c2f5bc873eec366af38a641e040eb @stronk7 stronk7 committed Mar 18, 2011
Showing with 79 additions and 23 deletions.
  1. +1 −1 admin/report/profiling/settings.php
  2. +7 −0 config-dist.php
  3. +12 −3 lib/setup.php
  4. +2 −4 lib/xhprof/readme_moodle.txt
  5. +57 −15 lib/xhprof/xhprof_moodle.php
@@ -3,6 +3,6 @@
defined('MOODLE_INTERNAL') || die;
// profiling report, added to development
-if (extension_loaded('xhprof') && function_exists('xhprof_enable') && !empty($CFG->profilingenabled)) {
+if (extension_loaded('xhprof') && function_exists('xhprof_enable') && (!empty($CFG->profilingenabled) || !empty($CFG->earlyprofilingenabled))) {
$ADMIN->add('development', new admin_externalpage('reportprofiling', get_string('pluginname', 'report_profiling'), "$CFG->wwwroot/$CFG->admin/report/profiling/index.php", 'moodle/site:config'));
}
View
@@ -297,6 +297,13 @@
// Print to footer (works with the default theme)
// define('MDL_PERFTOFOOT', true);
//
+// Enable earlier profiling that causes more code to be covered
+// on every request (db connections, config load, other inits...).
+// Requires extra configuration to be defined in config.php like:
+// profilingincluded, profilingexcluded, profilingautofrec,
+// profilingallowme, profilingallowall, profilinglifetime
+// $CFG->earlyprofilingenabled = true;
+//
// Force displayed usernames
// A little hack to anonymise user names for all students. If you set these
// then all non-teachers will always see these for every person.
View
@@ -228,6 +228,14 @@
define('MOODLE_INTERNAL', true);
}
+// Early profiling start, based exclusively on config.php $CFG settings
+if (!empty($CFG->earlyprofilingenabled)) {
+ require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
+ if (profiling_start()) {
+ register_shutdown_function('profiling_stop');
+ }
+}
+
/**
* Database connection. Used for all access to the database.
* @global moodle_database $DB
@@ -669,11 +677,12 @@ function stripslashes_deep($value) {
$SESSION = &$_SESSION['SESSION'];
$USER = &$_SESSION['USER'];
-// include and start profiling if needed, and register profiling_stop as shutdown function
+// Late profiling, only happening if early one wasn't started
if (!empty($CFG->profilingenabled)) {
require_once($CFG->libdir . '/xhprof/xhprof_moodle.php');
- profiling_start();
- register_shutdown_function('profiling_stop');
+ if (profiling_start()) {
+ register_shutdown_function('profiling_stop');
+ }
}
// Process theme change in the URL.
@@ -25,9 +25,6 @@ TODO:
* export/import profiling runs: Allow to pick any profile record, encapsulate
it into some serialized/encoded way and allow download/upload. It requires
DB changes in order to be able to specify the source of each record (own/imported).
- * move profiling start to earlier place: detect if all the needed $CFG->profilingXXX variables
- have been defined in config.php file and if that condition is fullfilled, start profiling
- @ the very first lines of setup.php (as early as possible).
* improvements to the listing mode: various commodity details like:
- allow to filter by various criteria
- inline (and ajax) editing of reference/comment and deleting
@@ -38,4 +35,5 @@ TODO:
- cpu times
(all them are right now enabled for everybody by default)
-20101122 - Eloy Lafuente (stronk7): Original import of 0.9.2 release
+20101122 - MDL-24600 - Eloy Lafuente (stronk7): Original import of 0.9.2 release
+20110318 - MDL-26891 - Eloy Lafuente (stronk7): Implemented earlier profiling runs
@@ -69,7 +69,7 @@ function profiling_start() {
}
// If profiling isn't enabled, nothing to start
- if (!$CFG->profilingenabled) {
+ if (empty($CFG->profilingenabled) && empty($CFG->earlyprofilingenabled)) {
return false;
}
@@ -78,32 +78,35 @@ function profiling_start() {
return false;
}
+ // Set script (from global if available, else our own)
+ $script = !empty($SCRIPT) ? $SCRIPT : profiling_get_script();
+
// Get PGC variables
$check = 'PROFILEME';
$profileme = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $profileme = $profileme && $CFG->profilingallowme;
+ $profileme = $profileme && !empty($CFG->profilingallowme);
$check = 'DONTPROFILEME';
$dontprofileme = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $dontprofileme = $dontprofileme && $CFG->profilingallowme;
+ $dontprofileme = $dontprofileme && !empty($CFG->profilingallowme);
$check = 'PROFILEALL';
$profileall = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $profileall = $profileall && $CFG->profilingallowall;
+ $profileall = $profileall && !empty($CFG->profilingallowall);
$check = 'PROFILEALLSTOP';
$profileallstop = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $profileallstop = $profileallstop && $CFG->profilingallowall;
+ $profileallstop = $profileallstop && !empty($CFG->profilingallowall);
// DONTPROFILEME detected, nothing to start
if ($dontprofileme) {
return false;
}
// PROFILEALLSTOP detected, clean the mark in seesion and continue
- if ($profileallstop) {
+ if ($profileallstop && !empty($SESSION)) {
unset($SESSION->profileall);
}
// PROFILEALL detected, set the mark in session and continue
- if ($profileall) {
+ if ($profileall && !empty($SESSION)) {
$SESSION->profileall = true;
// SESSION->profileall detected, set $profileall
@@ -113,21 +116,23 @@ function profiling_start() {
// Evaluate automatic (random) profiling if necessary
$profileauto = false;
- if ($CFG->profilingautofrec) {
+ if (!empty($CFG->profilingautofrec)) {
$profileauto = (mt_rand(1, $CFG->profilingautofrec) === 1);
}
- // See if the $SCRIPT matches any of the included patterns
- $profileincluded = profiling_string_matches($SCRIPT, $CFG->profilingincluded);
+ // See if the $script matches any of the included patterns
+ $included = empty($CFG->profilingincluded) ? '' : $CFG->profilingincluded;
+ $profileincluded = profiling_string_matches($script, $included);
- // See if the $SCRIPT matches any of the excluded patterns
- $profileexcluded = profiling_string_matches($SCRIPT, $CFG->profilingexcluded);
+ // See if the $script matches any of the excluded patterns
+ $excluded = empty($CFG->profilingexcluded) ? '' : $CFG->profilingexcluded;
+ $profileexcluded = profiling_string_matches($script, $excluded);
// Decide if profile auto must happen (observe matchings)
$profileauto = $profileauto && $profileincluded && !$profileexcluded;
// Decide if profile by match must happen (only if profileauto is disabled)
- $profilematch = $profileincluded && !$profileexcluded && !$CFG->profilingautofrec;
+ $profilematch = $profileincluded && !$profileexcluded && empty($CFG->profilingautofrec);
// If not auto, me, all, match have been detected, nothing to do
if (!$profileauto && !$profileme && !$profileall && !$profilematch) {
@@ -138,6 +143,9 @@ function profiling_start() {
$ignore = array('call_user_func', 'call_user_func_array');
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY, array('ignored_functions' => $ignore));
profiling_is_running(true);
+
+ // Started, return true
+ return true;
}
/**
@@ -152,7 +160,7 @@ function profiling_stop() {
}
// If profiling isn't enabled, nothing to stop
- if (!$CFG->profilingenabled) {
+ if (empty($CFG->profilingenabled) && empty($CFG->earlyprofilingenabled)) {
return false;
}
@@ -161,17 +169,23 @@ function profiling_stop() {
return false;
}
+ // Set script (from global if available, else our own)
+ $script = !empty($SCRIPT) ? $SCRIPT : profiling_get_script();
+
// Arrived here, profiling is running, stop and save everything
profiling_is_running(false);
$data = xhprof_disable();
$run = new moodle_xhprofrun();
- $run->prepare_run($SCRIPT);
+ $run->prepare_run($script);
$runid = $run->save_run($data, null);
profiling_is_saved(true);
// Prune old runs
profiling_prune_old_runs($runid);
+
+ // Finished, return true
+ return true;
}
function profiling_prune_old_runs($exception = 0) {
@@ -190,6 +204,34 @@ function profiling_prune_old_runs($exception = 0) {
runid != :exception', $params);
}
+/**
+ * Returns the path to the php script being requested
+ *
+ * Note this function is a partial copy of initialise_fullme() and
+ * setup_get_remote_url(), in charge of setting $FULLME, $SCRIPT and
+ * friends. To be used by early profiling runs in situations where
+ * $SCRIPT isn't defined yet
+ *
+ * @return string absolute path (wwwroot based) of the script being executed
+ */
+function profiling_get_script() {
+ global $CFG;
+
+ $wwwroot = parse_url($CFG->wwwroot);
+
+ if (!isset($wwwroot['path'])) {
+ $wwwroot['path'] = '';
+ }
+ $wwwroot['path'] .= '/';
+
+ $path = $_SERVER['SCRIPT_NAME'];
+
+ if (strpos($path, $wwwroot['path']) === 0) {
+ return substr($path, strlen($wwwroot['path']) - 1);
+ }
+ return '';
+}
+
function profiling_urls($report, $runid, $runid2 = null) {
global $CFG;

0 comments on commit c646dd2

Please sign in to comment.