Skip to content

Instantly share code, notes, and snippets.

@esimonetti
Last active February 20, 2019 10:04
Show Gist options
  • Save esimonetti/4c84541d49ee0828b31de91d30bcedb0 to your computer and use it in GitHub Desktop.
Save esimonetti/4c84541d49ee0828b31de91d30bcedb0 to your computer and use it in GitHub Desktop.
POC of Tideways profiling extension for Sugar 7.9.1.0 on PHP 7.1
<?php
// Enrico Simonetti
// enricosimonetti.com
//
// Original work: https://gist.github.com/lblockken/78a59273f2460b36eb127a7c2ee510a1
//
// 2017-07-31 on Sugar 7.9.1.0 with PHP 7.1
// filename: custom/include/SugarXHprof/TidewaysProf.php
/**
* Class TidewaysProf
*
* To enable profiling install PHP tideways module and add these lines to the config_override.php:
* $sugar_config['xhprof_config']['enable'] = true;
* $sugar_config['xhprof_config']['manager'] = 'TidewaysProf';
* $sugar_config['xhprof_config']['log_to'] = 'cache/profile_files';
* $sugar_config['xhprof_config']['sample_rate'] = 1;
* $sugar_config['xhprof_config']['flags'] = 0;
*
*/
use Sugarcrm\Sugarcrm\Performance\Dbal\XhprofLogger;
class TidewaysProf extends SugarXHprof
{
/**
* Populates configuration from $sugar_config to self properties
*/
protected static function loadConfig()
{
if (!empty($GLOBALS['sugar_config']['xhprof_config'])) {
foreach ($GLOBALS['sugar_config']['xhprof_config'] as $k => $v) {
if (isset($v) && property_exists(static::$manager, $k)) {
static::${$k} = $v;
}
}
}
if (!static::$enable) {
return;
}
// disabling profiler if Tideways extension is not loaded
if (extension_loaded('tideways') == false) {
static::$enable = false;
return;
}
if (static::$save_to == 'file') {
// using default directory for profiler if it is not set
if (empty(static::$log_to)) {
static::$log_to = sys_get_temp_dir();
error_log("Warning: Must specify directory location for Tideways runs. " .
"Trying " . static::$log_to . " as default. You should set "
. "\$sugar_config['xhprof_config']['log_to'] on sugar config override");
}
// disabling profiler if directory is not exist or is not writable
if (is_dir(static::$log_to) == false || is_writable(static::$log_to) == false) {
static::$enable = false;
}
}
// enable SugarXhprofLogger class for Doctrine
if (static::$enable && empty($GLOBALS['installing'])) {
$logger = DBManagerFactory::getDbalLogger();
$decorator = new XhprofLogger(static::$instance, $logger);
DBManagerFactory::setDbalLogger($decorator);
}
}
/**
* Tries to enabled xhprof if all settings were passed
*/
public function start()
{
if (static::$enable == false) {
return;
}
if (static::$sample_rate == 0) {
static::$enable = false;
return;
}
$rate = 1 / static::$sample_rate * 100;
if (rand(0, 100) > $rate) {
static::$enable = false;
return;
}
$this->resetSqlTracker();
$this->resetElasticTracker();
register_shutdown_function(array(
$this,
'end'
));
$this->startTime = isset($_SERVER['REQUEST_TIME_FLOAT']) ? $_SERVER['REQUEST_TIME_FLOAT'] : microtime(true);
tideways_enable(static::$flags, array(
'ignored_functions' => static::$ignored_functions
));
}
/**
* Tries to collect data from XHprof after call of 'start' method
*/
public function end()
{
if (!static::$enable) {
return;
}
static::$enable = false;
$origMemLimit = ini_get('memory_limit');
ini_set('memory_limit', static::$memory_limit);
$xhprofData = tideways_disable();
$wallTime = $xhprofData['main()']['wt'];
if ($wallTime > static::$filter_wt * 1000) {
$sqlQueries = count($this->sqlTracker['sql']);
$elasticQueries = count($this->elasticTracker['queries']);
$action = static::cleanActionString(static::detectAction());
$runName = implode('d', array(
str_replace('.', 'd', $this->startTime),
$wallTime,
$sqlQueries,
$elasticQueries
)) . '.' . $action;
$this->saveRun($runName, $xhprofData);
}
ini_set('memory_limit', $origMemLimit);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment