Source of file HeydayXhprof.php
Size: 8,667 Bytes - Last Modified: 2021-12-24T06:51:28+00:00
/var/www/docs.ssmods.com/process/src/code/HeydayXhprof.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 | <?php if (file_exists(__DIR__ . '/../../mysite/_config_xhprof.php')) { require_once __DIR__ . '/../../mysite/_config_xhprof.php'; } /** * HeydayXhprof * * @category SilverStripe_Module * @package Heyday * @author Cam Spiers <cameron@heyday.co.nz> * @license http://www.opensource.org/licenses/MIT MIT * @link http://heyday.co.nz */ /** * HeydayXhprof acts as a wrapper to `xhprof` providing useful tools for * starting and stopping `xhprof` profiling. * * @category SilverStripe_Module * @package Heyday * @author Cam Spiers <cameron@heyday.co.nz> * @license http://www.opensource.org/licenses/MIT MIT * @link http://heyday.co.nz */ class HeydayXhprof { const LINK_MODE_NONE = 0; const LINK_MODE_JS = 1; const LINK_MODE_LINK = 2; /** * Stores default flags used in `xhprof_enable` */ protected static $default_flags = false; /** * Stores the "app name"/profile name. Used in profile saving and * `HeydayXhprofRun` saving. */ protected static $app_name = false; /** * Stores whether or not profiling is currently in progress */ protected static $started = false; /** * Stores probability for use in profiling under load */ protected static $probability = 1; /** * @var int */ protected static $link_mode = 1; /** * Stores request url based exclusions */ protected static $exclusions = array( 'xhprof_html' ); /** * @param int $link_mode */ public static function setLinkMode($link_mode) { if (in_array($link_mode, array(self::LINK_MODE_NONE, self::LINK_MODE_JS, self::LINK_MODE_LINK))) { self::$link_mode = $link_mode; } else { user_error('Unknown link mode'); } } /** * @return int */ public static function getLinkMode() { return self::$link_mode; } /** * Set the probability for profiling under load * * @param int $probability The probability to be set. * Should be a from 0 to 1 inclusive * * @return null */ public static function setProbability($probability) { self::$probability = round(max(min(1, $probability), 0), 6); } /** * Get Probability * * @return int */ public static function getProbability() { return self::$probability; } /** * Test whether or not request should be profiled based on a probability. * * @param int $probability Optional probability to be set. * * @return bool */ public static function testProbability($probability = null) { if ($probability) { self::setProbability($probability); } if (self::$probability) { $unit = pow(10, strlen(self::$probability)); return mt_rand(1, $unit) <= self::$probability * $unit; } else { return false; } } /** * Add single url for exclusion * * @param string $exclusion Url to add to exclusion list * * @return null */ public static function addExclusion($exclusion) { self::$exclusions[] = $exclusion; } /** * Add an array of urls for exclusion. * * @param array $exclusions An array of exclusions to be merged on * to the exclusions list * * @return null */ public static function addExclusions(array $exclusions) { self::$exclusions = array_merge(self::$exclusions, $exclusions); } /** * Set exclusions * * @param array $exclusions An array of exclusions to set to the * exclusions list * * @return null */ public static function setExclusions(array $exclusions) { self::$exclusions = $exclusions; } /** * Get exclusions * * @return array */ public static function getExclusions() { return self::$exclusions; } /** * Check is url is excluded * * @param string $url A url to check if it is excluded by the * exclusions list * * @return bool */ public static function isExcluded($url) { foreach (self::$exclusions as $exclusion) { if (stripos($url, $exclusion) !== false) { return true; } } return false; } /** * Check if we are allowed to profile based on url. If allowed by url, * test probability. * * @param string $url A url to check if it is excluded by the * exclusions list * * @return bool */ public static function isAllowed($url) { return !self::isExcluded($url) && self::testProbability(); } /** * Start the profiling. * * @param boolean $app_name The "app name" for the profile save and Run save * * @param boolean $flags Flags for xhprof_enable call * * @return null */ public static function start($app_name = false, $flags = false) { if (extension_loaded('xhprof')) { if (self::$started) { user_error('You have already started xhprof'); } xhprof_enable($flags !== false ? $flags : self::getDefaultFlags()); register_shutdown_function(array(__CLASS__, 'end')); self::$started = true; if ($app_name) { self::setAppName($app_name); } } else { user_error('Xhprof extension not loaded'); } } /** * End the current profiling. * * @return null */ public static function end() { if (extension_loaded('xhprof') && self::isStarted()) { self::$started = false; $xhprof_runs = new XHProfRuns_Default(); $run_id = $xhprof_runs->save_run(xhprof_disable(), self::getAppName()); switch (self::$link_mode) { case self::LINK_MODE_NONE: break; case self::LINK_MODE_JS: echo sprintf( <<<JSCRIPT <script> var winName; if (winName = window.prompt('Specify a window for xhprof to open in', '_blank')) { window.open('%s', winName).focus(); } </script> JSCRIPT , self::getUrl($run_id) ); break; case self::LINK_MODE_LINK: echo self::getLink($run_id); break; } } else { user_error('Xhprof extension not loaded'); } } public static function getLink($run_id) { return sprintf( '<a href="%s" target="_blank">View xhprof run</a>', self::getUrl($run_id) ); } public static function getUrl($run_id) { return sprintf( '/vendor/lox/xhprof/xhprof_html/index.php?run=%s&source=%s&sort=wt', $run_id, self::getAppName() ); } /** * Return default flags, if they don't exists then set some reasonable alternatives. * * @return int */ public static function getDefaultFlags() { if (self::$default_flags === false) { self::$default_flags = XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY; } return self::$default_flags; } /** * Set default flags for use in profiling * * @param int $flags Flags to set * * @return null */ public static function setDefaultFlags($flags) { self::$default_flags = $flags; } /** * Get the app name for profile saving, if it doesn't exist then set it the SilverStripe project name * * @return string The app name */ public static function getAppName() { if (self::$app_name == false) { global $project; self::$app_name = $project; } return self::$app_name; } /** * Set the app name for profile saving and run saving. * * @param string $app_name App name to set * * @return null */ public static function setAppName($app_name) { self::$app_name = urlencode($app_name); } /** * Tests if profiling has been started * * @return boolean Started */ public static function isStarted() { return self::$started; } } |