/** * Start profiling with probability according to sample size. * * @return boolean whether profiling was started or not. */ public function startProfiling(Request $request = null) { if (!function_exists('xhprof_enable') && !function_exists('tideways_enable') || mt_rand(1, $this->container->getParameter('mjr_library_profiler.sample_size')) != 1 || !isset($_COOKIE['MJRProfiler']) || $_COOKIE['MJRProfiler'] != 'yes') { return false; } $this->collecting = true; $this->collectingRequest = $request; if (function_exists('xhprof_enable')) { xhprof_enable($this->getFlags()); if ($this->logger) { $this->logger->debug('Enabled XHProf'); } } else { tideways_enable($this->getFlags()); if ($this->logger) { $this->logger->debug('Enabled Tideways Profiler'); } } return true; }
public function enable($flags = 0, array $options = []) : ProviderInterface { $flags = empty($flags) ? TIDEWAYS_FLAGS_CPU | TIDEWAYS_FLAGS_MEMORY | TIDEWAYS_FLAGS_NO_BUILTINS : $flags; tideways_enable($flags, $options); return $this; }
unset($dir); if (!extension_loaded('mongo') && !extension_loaded('mongodb') && Xhgui_Config::read('save.handler') === 'mongodb') { error_log('xhgui - extension mongo not loaded'); return; } if (!Xhgui_Config::shouldRun()) { return; } if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) { $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true); } if (extension_loaded('uprofiler')) { uprofiler_enable(UPROFILER_FLAGS_CPU | UPROFILER_FLAGS_MEMORY); } else { if (extension_loaded('tideways')) { tideways_enable(TIDEWAYS_FLAGS_CPU | TIDEWAYS_FLAGS_MEMORY | TIDEWAYS_FLAGS_NO_SPANS); } else { if (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 4) { xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY | XHPROF_FLAGS_NO_BUILTINS); } else { xhprof_enable(XHPROF_FLAGS_CPU | XHPROF_FLAGS_MEMORY); } } } register_shutdown_function(function () { if (extension_loaded('uprofiler')) { $data['profile'] = uprofiler_disable(); } else { if (extension_loaded('tideways')) { $data['profile'] = tideways_disable(); } else {
/** * Start production profiling for the application. * * There are three modes for profiling: * * 1. Wall-time only profiling of the complete request (no overhead) * 2. Full profile/trace using xhprof (depending of # function calls * significant overhead) * 3. Whitelist-profiling mode only interesting functions. * (5-40% overhead, requires custom xhprof version >= 0.95) * * Decisions to profile are made based on a sample-rate and random picks. * You can influence the sample rate and pick a value that suites your * application. Applications with lower request rates need a much higher * transaction rate (25-50%) than applications with high load (<= 1%). * * Factors that influence sample rate: * * 1. Second parameter $sampleRate to start() method. * 2. _qprofiler Query Parameter (string key is deprecated or array) * 3. Cookie TIDEWAYS_SESSION * 4. TIDEWAYS_SAMPLERATE environment variable. * * start() automatically invokes a register shutdown handler that stops and * transmits the profiling data to the local daemon for further processing. * * @param array|string $options Either options array or api key (when string) * @param int $sampleRate Deprecated, use "sample_rate" key in options instead. * * @return void */ public static function start($options = array(), $sampleRate = null) { if (self::$mode !== self::MODE_NONE) { return; } if (!is_array($options)) { $options = array('api_key' => $options); } if ($sampleRate !== null) { $options['sample_rate'] = $sampleRate; } $defaults = array('api_key' => isset($_SERVER['TIDEWAYS_APIKEY']) ? $_SERVER['TIDEWAYS_APIKEY'] : ini_get("tideways.api_key"), 'sample_rate' => isset($_SERVER['TIDEWAYS_SAMPLERATE']) ? intval($_SERVER['TIDEWAYS_SAMPLERATE']) : ini_get("tideways.sample_rate"), 'collect' => isset($_SERVER['TIDEWAYS_COLLECT']) ? $_SERVER['TIDEWAYS_COLLECT'] : (ini_get("tideways.collect") ?: self::MODE_TRACING), 'monitor' => isset($_SERVER['TIDEWAYS_MONITOR']) ? $_SERVER['TIDEWAYS_MONITOR'] : (ini_get("tideways.monitor") ?: self::MODE_BASIC), 'distributed_tracing_hosts' => isset($_SERVER['TIDEWAYS_ALLOWED_HOSTS']) ? $_SERVER['TIDEWAYS_ALLOWED_HOSTS'] : (ini_get("tideways.distributed_tracing_hosts") ?: '127.0.0.1'), 'distributed_trace' => null); $options = array_merge($defaults, $options); if (strlen((string) $options['api_key']) === 0) { return; } self::init($options['api_key'], $options['distributed_trace'], $options['distributed_tracing_hosts']); self::$mode = self::decideProfiling($options['sample_rate'], $options); if (self::$extension === self::EXTENSION_TIDEWAYS) { switch (self::$mode) { case self::MODE_FULL: $flags = 0; break; case self::MODE_PROFILING: $flags = TIDEWAYS_FLAGS_NO_SPANS; break; case self::MODE_TRACING: $flags = TIDEWAYS_FLAGS_NO_HIERACHICAL; break; default: $flags = TIDEWAYS_FLAGS_NO_COMPILE | TIDEWAYS_FLAGS_NO_USERLAND | TIDEWAYS_FLAGS_NO_BUILTINS; break; } self::$currentRootSpan = new \Tideways\Traces\TwExtensionSpan(0); tideways_enable($flags, self::$defaultOptions); if (($flags & TIDEWAYS_FLAGS_NO_SPANS) === 0) { foreach (self::$defaultOptions['watches'] as $watch => $category) { tideways_span_watch($watch, $category); } foreach (self::$defaultOptions['callbacks'] as $function => $callback) { tideways_span_callback($function, $callback); } } } elseif (self::$extension === self::EXTENSION_XHPROF && (self::$mode & self::MODE_PROFILING) > 0) { \Tideways\Traces\PhpSpan::clear(); self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app'); self::$currentRootSpan->startTimer(); xhprof_enable(0, self::$defaultOptions); } else { \Tideways\Traces\PhpSpan::clear(); self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app'); self::$currentRootSpan->startTimer(); } }
/** * Enable the profiler in the given $mode. * * @param string $mode * @return void */ private static function enableProfiler($mode) { self::$mode = $mode; if (self::$extension === self::EXTENSION_TIDEWAYS && self::$mode !== self::MODE_NONE) { switch (self::$mode) { case self::MODE_FULL: $flags = 0; break; case self::MODE_PROFILING: $flags = TIDEWAYS_FLAGS_NO_SPANS; break; case self::MODE_TRACING: $flags = TIDEWAYS_FLAGS_NO_HIERACHICAL; break; default: $flags = TIDEWAYS_FLAGS_NO_COMPILE | TIDEWAYS_FLAGS_NO_USERLAND | TIDEWAYS_FLAGS_NO_BUILTINS; break; } self::$currentRootSpan = new \Tideways\Traces\TwExtensionSpan(0); tideways_enable($flags, self::$defaultOptions); if (($flags & TIDEWAYS_FLAGS_NO_SPANS) === 0) { foreach (self::$defaultOptions['watches'] as $watch => $category) { tideways_span_watch($watch, $category); } foreach (self::$defaultOptions['callbacks'] as $function => $callback) { tideways_span_callback($function, $callback); } } self::log(2, "Starting tideways extension for " . self::$trace['apiKey'] . " with mode: " . $mode); } elseif (self::$extension === self::EXTENSION_XHPROF && (self::$mode & self::MODE_PROFILING) > 0) { \Tideways\Traces\PhpSpan::clear(); self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app'); self::$currentRootSpan->startTimer(); xhprof_enable(0, self::$defaultOptions); self::log(2, "Starting xhprof extension for " . self::$trace['apiKey'] . " with mode: " . $mode); } else { \Tideways\Traces\PhpSpan::clear(); self::$currentRootSpan = new \Tideways\Traces\PhpSpan(0, 'app'); self::$currentRootSpan->startTimer(); self::log(2, "Starting non-extension based tracing for " . self::$trace['apiKey'] . " with mode: " . $mode); } }
/** * 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') && !extension_loaded('tideways')) { 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'); if (extension_loaded('tideways')) { tideways_enable(TIDEWAYS_FLAGS_CPU + TIDEWAYS_FLAGS_MEMORY, array('ignored_functions' => $ignore)); } else { xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY, array('ignored_functions' => $ignore)); } profiling_is_running(true); // Started, return true return true; }