Completely disable Debug logging if it is not enabled for the current user

관리자 또는 특정 IP에서만 디버그 기능을 사용하도록 설정된 경우,
그 밖의 요청에서는 어떤 에러메시지, 쿼리, 트리거 소요시간 등의 기록도
디버그 클래스에 저장하지 않도록 변경합니다.

워닝이 많이 발생하는 PHP 8.0에서는 20~30%의 성능 개선 효과가 있습니다.
This commit is contained in:
Kijin Sung 2021-01-07 02:51:43 +09:00
parent 02122cb383
commit 1a204d8c52
11 changed files with 108 additions and 74 deletions

View file

@ -175,7 +175,7 @@ class DisplayHandler extends Handler
} }
// Check if debugging is enabled for this request. // Check if debugging is enabled for this request.
if (!config('debug.enabled') || !Rhymix\Framework\Debug::isEnabledForCurrentUser()) if (!Rhymix\Framework\Debug::isEnabledForCurrentUser())
{ {
return; return;
} }

View file

@ -273,10 +273,12 @@ class HTMLDisplayHandler
$oModuleController->replaceDefinedLangCode($output); $oModuleController->replaceDefinedLangCode($output);
// remove template path comment tag // remove template path comment tag
/*
if(!Rhymix\Framework\Debug::isEnabledForCurrentUser()) if(!Rhymix\Framework\Debug::isEnabledForCurrentUser())
{ {
$output = preg_replace('/\n<!-- Template (?:start|end) : .*? -->\r?\n/', "\n", $output); $output = preg_replace('/\n<!-- Template (?:start|end) : .*? -->\r?\n/', "\n", $output);
} }
*/
} }
/** /**

View file

@ -344,29 +344,32 @@ class FileHandler
$log['status'] = $response ? $response->status_code : 0; $log['status'] = $response ? $response->status_code : 0;
$log['elapsed_time'] = $elapsed_time; $log['elapsed_time'] = $elapsed_time;
if (config('debug.enabled') && in_array('slow_remote_requests', config('debug.display_content'))) if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
{ {
$bt = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); if (in_array('slow_remote_requests', config('debug.display_content')))
foreach($bt as $no => $call)
{ {
if(strncasecmp($call['function'], 'getRemote', 9) === 0) $bt = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
foreach($bt as $no => $call)
{ {
$call_no = $no + 1; if(strncasecmp($call['function'], 'getRemote', 9) === 0)
$log['called_file'] = $bt[$call_no]['file']; {
$log['called_line'] = $bt[$call_no]['line']; $call_no = $no + 1;
$call_no++; $log['called_file'] = $bt[$call_no]['file'];
$log['called_method'] = $bt[$call_no]['class'].$bt[$call_no]['type'].$bt[$call_no]['function']; $log['called_line'] = $bt[$call_no]['line'];
$log['backtrace'] = array_slice($bt, $call_no, 1); $call_no++;
break; $log['called_method'] = $bt[$call_no]['class'].$bt[$call_no]['type'].$bt[$call_no]['function'];
$log['backtrace'] = array_slice($bt, $call_no, 1);
break;
}
} }
} }
else
{
$log['called_file'] = $log['called_line'] = $log['called_method'] = null;
$log['backtrace'] = array();
}
Rhymix\Framework\Debug::addRemoteRequest($log);
} }
else
{
$log['called_file'] = $log['called_line'] = $log['called_method'] = null;
$log['backtrace'] = array();
}
Rhymix\Framework\Debug::addRemoteRequest($log);
foreach($response->cookies as $cookie) foreach($response->cookies as $cookie)
{ {

View file

@ -1229,12 +1229,15 @@ class ModuleHandler extends Handler
{ {
$trigger_target = $module . ($type === 'class' ? '' : $type) . '.' . $called_method; $trigger_target = $module . ($type === 'class' ? '' : $type) . '.' . $called_method;
Rhymix\Framework\Debug::addTrigger(array( if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
'name' => $trigger_name . '.' . $called_position, {
'target' => $trigger_target, Rhymix\Framework\Debug::addTrigger(array(
'target_plugin' => $module, 'name' => $trigger_name . '.' . $called_position,
'elapsed_time' => $after_each_trigger_time - $before_each_trigger_time, 'target' => $trigger_target,
)); 'target_plugin' => $module,
'elapsed_time' => $after_each_trigger_time - $before_each_trigger_time,
));
}
} }
if($output instanceof BaseObject && !$output->toBool()) if($output instanceof BaseObject && !$output->toBool())
@ -1280,12 +1283,15 @@ class ModuleHandler extends Handler
$trigger_target = 'closure'; $trigger_target = 'closure';
} }
Rhymix\Framework\Debug::addTrigger(array( if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
'name' => $trigger_name . '.' . $called_position, {
'target' => $trigger_target, Rhymix\Framework\Debug::addTrigger(array(
'target_plugin' => null, 'name' => $trigger_name . '.' . $called_position,
'elapsed_time' => $after_each_trigger_time - $before_each_trigger_time, 'target' => $trigger_target,
)); 'target_plugin' => null,
'elapsed_time' => $after_each_trigger_time - $before_each_trigger_time,
));
}
} }
if(is_object($output) && method_exists($output, 'toBool') && !$output->toBool()) if(is_object($output) && method_exists($output, 'toBool') && !$output->toBool())

View file

@ -530,7 +530,11 @@ class DB
{ {
$this->setError(-1, $e->getMessage()); $this->setError(-1, $e->getMessage());
} }
Debug::addQuery($this->getQueryLog('START TRANSACTION', 0));
if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($this->getQueryLog('START TRANSACTION', 0));
}
} }
$this->_transaction_level++; $this->_transaction_level++;
return $this->_transaction_level; return $this->_transaction_level;
@ -554,7 +558,11 @@ class DB
{ {
$this->setError(-1, $e->getMessage()); $this->setError(-1, $e->getMessage());
} }
Debug::addQuery($this->getQueryLog('ROLLBACK', 0));
if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($this->getQueryLog('ROLLBACK', 0));
}
} }
$this->_transaction_level--; $this->_transaction_level--;
return $this->_transaction_level; return $this->_transaction_level;
@ -578,7 +586,11 @@ class DB
{ {
$this->setError(-1, $e->getMessage()); $this->setError(-1, $e->getMessage());
} }
Debug::addQuery($this->getQueryLog('COMMIT', 0));
if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($this->getQueryLog('COMMIT', 0));
}
} }
$this->_transaction_level--; $this->_transaction_level--;
return $this->_transaction_level; return $this->_transaction_level;
@ -1060,12 +1072,7 @@ class DB
public function getQueryLog(string $query, float $elapsed_time): array public function getQueryLog(string $query, float $elapsed_time): array
{ {
// Cache the debug status to improve performance. // Cache the debug status to improve performance.
static $debug_enabled = null;
static $debug_queries = null; static $debug_queries = null;
if ($debug_enabled === null)
{
$debug_enabled = Config::get('debug.enabled');
}
if ($debug_queries === null) if ($debug_queries === null)
{ {
$debug_queries = in_array('queries', Config::get('debug.display_content') ?: []); $debug_queries = in_array('queries', Config::get('debug.display_content') ?: []);
@ -1087,7 +1094,7 @@ class DB
); );
// Add debug information if enabled. // Add debug information if enabled.
if ($debug_enabled && ($this->_errno || $debug_queries)) if ($this->_errno || $debug_queries)
{ {
$backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
foreach ($backtrace as $no => $call) foreach ($backtrace as $no => $call)

View file

@ -10,7 +10,8 @@ class Debug
/** /**
* Store log entries here. * Store log entries here.
*/ */
protected static $_enabled = true; protected static $_enabled = null;
protected static $_config = array();
protected static $_aliases = array(); protected static $_aliases = array();
protected static $_entries = array(); protected static $_entries = array();
protected static $_errors = array(); protected static $_errors = array();
@ -286,7 +287,7 @@ class Debug
self::$_entries[] = $entry; self::$_entries[] = $entry;
// Add the entry to the error log. // Add the entry to the error log.
if (config('debug.write_error_log') === 'all' && self::isEnabledForCurrentUser()) if (self::$_config['write_error_log'] === 'all')
{ {
$log_entry = str_replace("\0", '', sprintf('Rhymix Debug: %s in %s on line %d', $log_entry = str_replace("\0", '', sprintf('Rhymix Debug: %s in %s on line %d',
var_export($message, true), $entry->file, $entry->line)); var_export($message, true), $entry->file, $entry->line));
@ -341,7 +342,7 @@ class Debug
); );
// Add the entry to the error log. // Add the entry to the error log.
if (config('debug.write_error_log') === 'all') if (self::$_config['write_error_log'] === 'all')
{ {
$log_entry = strtr(sprintf('PHP %s: %s in %s on line %d', $errinfo->type, $errstr, $errfile, intval($errline)), "\0\r\n\t\v\e\f", ' '); $log_entry = strtr(sprintf('PHP %s: %s in %s on line %d', $errinfo->type, $errstr, $errfile, intval($errline)), "\0\r\n\t\v\e\f", ' ');
error_log($log_entry . \PHP_EOL . self::formatBacktrace($backtrace)); error_log($log_entry . \PHP_EOL . self::formatBacktrace($backtrace));
@ -394,7 +395,7 @@ class Debug
self::$_errors[] = $error_object; self::$_errors[] = $error_object;
if (config('debug.write_error_log') === 'all') if (self::$_config['write_error_log'] === 'all')
{ {
$log_entry = strtr(sprintf('Query Error: %s in %s on line %d', $error_object->message, $error_object->file, intval($error_object->line)), "\0\r\n\t\v\e\f", ' '); $log_entry = strtr(sprintf('Query Error: %s in %s on line %d', $error_object->message, $error_object->file, intval($error_object->line)), "\0\r\n\t\v\e\f", ' ');
error_log($log_entry . \PHP_EOL . self::formatBacktrace($error_object->backtrace)); error_log($log_entry . \PHP_EOL . self::formatBacktrace($error_object->backtrace));
@ -402,7 +403,7 @@ class Debug
} }
// Add the entry to the slow query log. // Add the entry to the slow query log.
if ($query_object->query_time && $query_object->query_time >= config('debug.log_slow_queries')) if ($query_object->query_time && $query_object->query_time >= self::$_config['log_slow_queries'])
{ {
self::$_slow_queries[] = $query_object; self::$_slow_queries[] = $query_object;
} }
@ -436,7 +437,7 @@ class Debug
); );
self::$_triggers[] = $trigger_object; self::$_triggers[] = $trigger_object;
if ($trigger_object->trigger_time && $trigger_object->trigger_time >= config('debug.log_slow_triggers')) if ($trigger_object->trigger_time && $trigger_object->trigger_time >= self::$_config['log_slow_triggers'])
{ {
self::$_slow_triggers[] = $trigger_object; self::$_slow_triggers[] = $trigger_object;
} }
@ -468,7 +469,7 @@ class Debug
); );
self::$_widgets[] = $widget_object; self::$_widgets[] = $widget_object;
if ($widget_object->widget_time && $widget_object->widget_time >= config('debug.log_slow_widgets')) if ($widget_object->widget_time && $widget_object->widget_time >= self::$_config['log_slow_widgets'])
{ {
self::$_slow_widgets[] = $widget_object; self::$_slow_widgets[] = $widget_object;
} }
@ -502,7 +503,7 @@ class Debug
); );
self::$_remote_requests[] = $request_object; self::$_remote_requests[] = $request_object;
if ($request_object->elapsed_time && $request_object->elapsed_time >= config('debug.log_slow_remote_requests')) if ($request_object->elapsed_time && $request_object->elapsed_time >= self::$_config['log_slow_remote_requests'])
{ {
self::$_slow_remote_requests[] = $request_object; self::$_slow_remote_requests[] = $request_object;
} }
@ -549,7 +550,7 @@ class Debug
$log_entry = str_replace("\0", '', sprintf('%s #%d "%s" in %s on line %d', $log_entry = str_replace("\0", '', sprintf('%s #%d "%s" in %s on line %d',
get_class($e), $e->getCode(), $e->getMessage(), $errfile, $e->getLine())); get_class($e), $e->getCode(), $e->getMessage(), $errfile, $e->getLine()));
} }
if (config('debug.write_error_log') !== 'none') if (self::$_config['write_error_log'] !== 'none')
{ {
error_log('PHP Exception: ' . $log_entry . \PHP_EOL . self::formatBacktrace($e->getTrace())); error_log('PHP Exception: ' . $log_entry . \PHP_EOL . self::formatBacktrace($e->getTrace()));
} }
@ -579,7 +580,7 @@ class Debug
// Add the entry to the error log. // Add the entry to the error log.
$message = sprintf('%s in %s on line %d', $errinfo['message'], $errinfo['file'], intval($errinfo['line'])); $message = sprintf('%s in %s on line %d', $errinfo['message'], $errinfo['file'], intval($errinfo['line']));
$log_entry = str_replace("\0", '', 'PHP ' . self::getErrorType($errinfo['type']) . ': ' . $message); $log_entry = str_replace("\0", '', 'PHP ' . self::getErrorType($errinfo['type']) . ': ' . $message);
if (config('debug.write_error_log') !== 'none') if (self::$_config['write_error_log'] !== 'none')
{ {
error_log($log_entry); error_log($log_entry);
} }
@ -633,6 +634,7 @@ class Debug
*/ */
public static function registerErrorHandlers($error_types) public static function registerErrorHandlers($error_types)
{ {
self::$_config = config('debug');
set_error_handler('\\Rhymix\\Framework\\Debug::addError', $error_types); set_error_handler('\\Rhymix\\Framework\\Debug::addError', $error_types);
set_exception_handler('\\Rhymix\\Framework\\Debug::exceptionHandler'); set_exception_handler('\\Rhymix\\Framework\\Debug::exceptionHandler');
register_shutdown_function('\\Rhymix\\Framework\\Debug::shutdownHandler'); register_shutdown_function('\\Rhymix\\Framework\\Debug::shutdownHandler');
@ -712,45 +714,43 @@ class Debug
*/ */
public static function isEnabledForCurrentUser() public static function isEnabledForCurrentUser()
{ {
static $cache = null; if (self::$_enabled !== null)
if ($cache !== null)
{ {
return $cache; return self::$_enabled;
} }
if (!Config::get('debug.enabled')) if (!self::$_config['enabled'])
{ {
return $cache = false; return self::$_enabled = false;
} }
$display_to = Config::get('debug.display_to'); switch (self::$_config['display_to'])
switch ($display_to)
{ {
case 'everyone': case 'everyone':
return $cache = true; return self::$_enabled = true;
case 'ip': case 'ip':
if (Filters\IpFilter::inRanges(\RX_CLIENT_IP, Config::get('debug.allow'))) if (Filters\IpFilter::inRanges(\RX_CLIENT_IP, self::$_config['allow']))
{ {
return $cache = true; return self::$_enabled = true;
} }
if (\RX_CLIENT_IP === '127.0.0.1' || \RX_CLIENT_IP === '::1') if (\RX_CLIENT_IP === '127.0.0.1' || \RX_CLIENT_IP === '::1')
{ {
return $cache = true; return self::$_enabled = true;
} }
if (\RX_CLIENT_IP === $_SERVER['SERVER_ADDR'] || \RX_CLIENT_IP === $_SERVER['LOCAL_ADDR']) if (\RX_CLIENT_IP === $_SERVER['SERVER_ADDR'] || \RX_CLIENT_IP === $_SERVER['LOCAL_ADDR'])
{ {
return $cache = true; return self::$_enabled = true;
} }
return $cache = false; return self::$_enabled = false;
case 'admin': case 'admin':
default: default:
$logged_info = \Context::get('logged_info'); $logged_info = \Context::get('logged_info');
if ($logged_info && $logged_info->is_admin === 'Y') if ($logged_info && $logged_info->is_admin === 'Y')
{ {
return $cache = true; return self::$_enabled = true;
} }
return $cache = false; return self::$_enabled = false;
} }
} }

View file

@ -61,7 +61,10 @@ class DBHelper extends \PDO
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
$db_class->setError(-1, $e->getMessage()); $db_class->setError(-1, $e->getMessage());
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
/** /**
* This is a new feature in Rhymix 2.0 so we don't have to mess * This is a new feature in Rhymix 2.0 so we don't have to mess
@ -110,7 +113,10 @@ class DBHelper extends \PDO
{ {
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time));
}
} }
return $stmt; return $stmt;
@ -140,7 +146,10 @@ class DBHelper extends \PDO
{ {
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($query, $elapsed_time)); if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($db_class->getQueryLog($query, $elapsed_time));
}
} }
return $result; return $result;

View file

@ -57,7 +57,10 @@ class DBStmtHelper extends \PDOStatement
{ {
$elapsed_time = microtime(true) - $start_time; $elapsed_time = microtime(true) - $start_time;
$db_class->addElapsedTime($elapsed_time); $db_class->addElapsedTime($elapsed_time);
Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time)); if (Debug::isEnabledForCurrentUser())
{
Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time));
}
} }
return $result; return $result;

View file

@ -130,7 +130,7 @@ class addonController extends addon
$buff[] = 'if ($run && file_exists($addon_file)):'; $buff[] = 'if ($run && file_exists($addon_file)):';
$buff[] = ' include($addon_file);'; $buff[] = ' include($addon_file);';
$buff[] = ' $after_time = microtime(true);'; $buff[] = ' $after_time = microtime(true);';
$buff[] = ' if (class_exists("Rhymix\\\\Framework\\\\Debug")):'; $buff[] = ' if (class_exists("Rhymix\\\\Framework\\\\Debug") && Rhymix\\Framework\\Debug::isEnabledForCurrentUser()):';
$buff[] = ' Rhymix\\Framework\\Debug::addTrigger(array('; $buff[] = ' Rhymix\\Framework\\Debug::addTrigger(array(';
$buff[] = ' "name" => "addon." . $called_position,'; $buff[] = ' "name" => "addon." . $called_position,';
$buff[] = ' "target" => "' . $addon . '",'; $buff[] = ' "target" => "' . $addon . '",';

View file

@ -652,11 +652,14 @@ class widgetController extends widget
$GLOBALS['__widget_excute_elapsed__'] = 0; $GLOBALS['__widget_excute_elapsed__'] = 0;
} }
$GLOBALS['__widget_excute_elapsed__'] += $elapsed_time; $GLOBALS['__widget_excute_elapsed__'] += $elapsed_time;
Rhymix\Framework\Debug::addWidget(array( if (Rhymix\Framework\Debug::isEnabledForCurrentUser())
'name' => $widget, {
'elapsed_time' => $elapsed_time, Rhymix\Framework\Debug::addWidget(array(
)); 'name' => $widget,
'elapsed_time' => $elapsed_time,
));
}
// Return result // Return result
return $output; return $output;
} }

View file

@ -6,6 +6,7 @@ class DebugTest extends \Codeception\TestCase\Test
public function _before() public function _before()
{ {
Rhymix\Framework\Debug::enable();
$this->error_log = ini_get('error_log'); $this->error_log = ini_get('error_log');
ini_set('error_log', '/dev/null'); ini_set('error_log', '/dev/null');
} }