/lib/xhprof/xhprof_moodle.php
PHP | 584 lines | 340 code | 93 blank | 151 comment | 57 complexity | db7168572820bd9f7e9d152ae1cbc9f4 MD5 | raw file
- <?php
- // This file is part of Moodle - http://moodle.org/
- //
- // Moodle 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 3 of the License, or
- // (at your option) any later version.
- //
- // Moodle 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 Moodle. If not, see <http://www.gnu.org/licenses/>.
- /**
- * @package core
- * @subpackage profiling
- * @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
- defined('MOODLE_INTERNAL') || die();
- // need some stuff from xhprof
- require_once($CFG->libdir . '/xhprof/xhprof_lib/utils/xhprof_lib.php');
- require_once($CFG->libdir . '/xhprof/xhprof_lib/utils/xhprof_runs.php');
- // need some stuff from moodle
- require_once($CFG->libdir.'/tablelib.php');
- // TODO: Change the implementation below to proper profiling class
- /**
- * Returns if profiling is running, optionally setting it
- */
- function profiling_is_running($value = null) {
- static $running = null;
- if (!is_null($value)) {
- $running = (bool)$value;
- }
- return $running;
- }
- /**
- * Returns if profiling has been saved, optionally setting it
- */
- function profiling_is_saved($value = null) {
- static $saved = null;
- if (!is_null($value)) {
- $saved = (bool)$value;
- }
- return $saved;
- }
- /**
- * Start profiling observing all the configuration
- */
- function profiling_start() {
- global $CFG, $SESSION, $SCRIPT;
- // If profiling isn't available, nothing to start
- if (!extension_loaded('xhprof') || !function_exists('xhprof_enable')) {
- return false;
- }
- // If profiling isn't enabled, nothing to start
- if (empty($CFG->profilingenabled) && empty($CFG->earlyprofilingenabled)) {
- return false;
- }
- // If profiling is already running or saved, nothing to start
- if (profiling_is_running() || profiling_is_saved()) {
- 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 && !empty($CFG->profilingallowme);
- $check = 'DONTPROFILEME';
- $dontprofileme = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $dontprofileme = $dontprofileme && !empty($CFG->profilingallowme);
- $check = 'PROFILEALL';
- $profileall = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $profileall = $profileall && !empty($CFG->profilingallowall);
- $check = 'PROFILEALLSTOP';
- $profileallstop = isset($_POST[$check]) || isset($_GET[$check]) || isset($_COOKIE[$check]) ? true : false;
- $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 && !empty($SESSION)) {
- unset($SESSION->profileall);
- }
- // PROFILEALL detected, set the mark in session and continue
- if ($profileall && !empty($SESSION)) {
- $SESSION->profileall = true;
- // SESSION->profileall detected, set $profileall
- } else if (!empty($SESSION->profileall)) {
- $profileall = true;
- }
- // Evaluate automatic (random) profiling if necessary
- $profileauto = false;
- if (!empty($CFG->profilingautofrec)) {
- $profileauto = (mt_rand(1, $CFG->profilingautofrec) === 1);
- }
- // 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
- $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 && empty($CFG->profilingautofrec);
- // If not auto, me, all, match have been detected, nothing to do
- if (!$profileauto && !$profileme && !$profileall && !$profilematch) {
- return false;
- }
- // Arrived here, the script is going to be profiled, let's do it
- $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;
- }
- /**
- * Stop profiling, gathering results and storing them
- */
- function profiling_stop() {
- global $CFG, $DB, $SCRIPT;
- // If profiling isn't available, nothing to stop
- if (!extension_loaded('xhprof') || !function_exists('xhprof_enable')) {
- return false;
- }
- // If profiling isn't enabled, nothing to stop
- if (empty($CFG->profilingenabled) && empty($CFG->earlyprofilingenabled)) {
- return false;
- }
- // If profiling is not running or is already saved, nothing to stop
- if (!profiling_is_running() || profiling_is_saved()) {
- 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();
- // We only save the run after ensuring the DB table exists
- // (this prevents problems with profiling runs enabled in
- // config.php before Moodle is installed. Rare but...
- $tables = $DB->get_tables();
- if (!in_array('profiling', $tables)) {
- return false;
- }
- $run = new moodle_xhprofrun();
- $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) {
- global $CFG, $DB;
- // Setting to 0 = no prune
- if (empty($CFG->profilinglifetime)) {
- return;
- }
- $cuttime = time() - ($CFG->profilinglifetime * 60);
- $params = array('cuttime' => $cuttime, 'exception' => $exception);
- $DB->delete_records_select('profiling', 'runreference = 0 AND
- timecreated < :cuttime AND
- 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;
- $url = '';
- switch ($report) {
-