Logging update for class/method trace
This commit is contained in:
@@ -556,7 +556,7 @@ class Backend
|
|||||||
string $suffix = '',
|
string $suffix = '',
|
||||||
int $min_steps = 1,
|
int $min_steps = 1,
|
||||||
bool $name_pos_back = false
|
bool $name_pos_back = false
|
||||||
) {
|
): string {
|
||||||
// get the build layout
|
// get the build layout
|
||||||
$html_time = \CoreLibs\Output\Form\Elements::printDateTime(
|
$html_time = \CoreLibs\Output\Form\Elements::printDateTime(
|
||||||
$year,
|
$year,
|
||||||
|
|||||||
@@ -805,7 +805,10 @@ class IO
|
|||||||
$call_stack[] =
|
$call_stack[] =
|
||||||
($call_trace['file'] ?? 'n/f') . ':'
|
($call_trace['file'] ?? 'n/f') . ':'
|
||||||
. ($call_trace['line'] ?? '-') . ':'
|
. ($call_trace['line'] ?? '-') . ':'
|
||||||
. (!empty($call_trace['class']) ? $call_trace['class'] . '->' : '')
|
. (!empty($call_trace['class']) ?
|
||||||
|
$call_trace['class'] . ($call_trace['type'] ?? '') :
|
||||||
|
''
|
||||||
|
)
|
||||||
. $call_trace['function'];
|
. $call_trace['function'];
|
||||||
}
|
}
|
||||||
$context = [
|
$context = [
|
||||||
@@ -825,7 +828,7 @@ class IO
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// used named arguments so we can easy change the order of debug
|
// used named arguments so we can easy change the order of debug
|
||||||
$this->log->debug(
|
$this->log->debug(
|
||||||
group_id: $debug_id,
|
group_id: $debug_id,
|
||||||
message: $error_string,
|
message: $error_string,
|
||||||
|
|||||||
@@ -405,7 +405,7 @@ class LoggingLegacy
|
|||||||
// set per class, but don't use get_class as we will only get self
|
// set per class, but don't use get_class as we will only get self
|
||||||
$rpl_string = !$this->log_per_class ? '' : '_'
|
$rpl_string = !$this->log_per_class ? '' : '_'
|
||||||
// set sub class settings
|
// set sub class settings
|
||||||
. str_replace('\\', '-', Support::getCallerClass());
|
. str_replace('\\', '-', Support::getCallerTopLevelClass());
|
||||||
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
|
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
|
||||||
|
|
||||||
// if request to write to one file
|
// if request to write to one file
|
||||||
@@ -756,7 +756,7 @@ class LoggingLegacy
|
|||||||
return $status;
|
return $status;
|
||||||
}
|
}
|
||||||
// get the last class entry and wrie that
|
// get the last class entry and wrie that
|
||||||
$class = Support::getCallerClass();
|
$class = Support::getCallerTopLevelClass();
|
||||||
// get timestamp
|
// get timestamp
|
||||||
$timestamp = Support::printTime();
|
$timestamp = Support::printTime();
|
||||||
// same string put for print (no html data inside)
|
// same string put for print (no html data inside)
|
||||||
@@ -855,7 +855,7 @@ class LoggingLegacy
|
|||||||
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
|
. 'border-bottom: 1px solid black; margin: 10px 0 10px 0; '
|
||||||
. 'background-color: white; color: black;">'
|
. 'background-color: white; color: black;">'
|
||||||
. '<div style="font-size: 12px;">{<span style="font-style: italic; color: #928100;">'
|
. '<div style="font-size: 12px;">{<span style="font-style: italic; color: #928100;">'
|
||||||
. Support::getCallerClass() . '</span>}</div>';
|
. Support::getCallerTopLevelClass() . '</span>}</div>';
|
||||||
$string_output = $string_prefix . $string_output
|
$string_output = $string_prefix . $string_output
|
||||||
. '<div><span style="font-style: italic; color: #108db3;">Script Run Time:</span> '
|
. '<div><span style="font-style: italic; color: #108db3;">Script Run Time:</span> '
|
||||||
. $script_end . '</div>'
|
. $script_end . '</div>'
|
||||||
|
|||||||
@@ -79,10 +79,10 @@ class Support
|
|||||||
* default true: true, false: false
|
* default true: true, false: false
|
||||||
*
|
*
|
||||||
* @param bool $bool Variable to convert
|
* @param bool $bool Variable to convert
|
||||||
* @param string $name [default: ''] Prefix name
|
* @param string $name [=''] Prefix name
|
||||||
* @param string $true [default: 'true'] True string
|
* @param string $true [='true'] True string
|
||||||
* @param string $false [default: 'false'] False string
|
* @param string $false [='false'] False string
|
||||||
* @param bool $no_html [default: false] if true do not print html
|
* @param bool $no_html [=false] if true do not print html
|
||||||
* @return string String with converted bool text for debug
|
* @return string String with converted bool text for debug
|
||||||
*/
|
*/
|
||||||
public static function printBool(
|
public static function printBool(
|
||||||
@@ -104,8 +104,8 @@ class Support
|
|||||||
* Convert bool value to string value. Short name alias for printBool
|
* Convert bool value to string value. Short name alias for printBool
|
||||||
*
|
*
|
||||||
* @param bool $bool Bool value to be transformed
|
* @param bool $bool Bool value to be transformed
|
||||||
* @param string $true [default: 'true'] Override default string 'true'
|
* @param string $true [='true'] Override default string 'true'
|
||||||
* @param string $false [default: 'false'] Override default string 'false'
|
* @param string $false [=false'] Override default string 'false'
|
||||||
* @return string $true or $false string for true/false bool
|
* @return string $true or $false string for true/false bool
|
||||||
*/
|
*/
|
||||||
public static function prBl(
|
public static function prBl(
|
||||||
@@ -159,7 +159,7 @@ class Support
|
|||||||
* Recommended debug output
|
* Recommended debug output
|
||||||
*
|
*
|
||||||
* @param mixed $data Anything
|
* @param mixed $data Anything
|
||||||
* @param bool $no_html [default=false] If true strip all html tags
|
* @param bool $no_html [=false] If true strip all html tags
|
||||||
* (for text print)
|
* (for text print)
|
||||||
* @return string A text string
|
* @return string A text string
|
||||||
*/
|
*/
|
||||||
@@ -203,7 +203,7 @@ class Support
|
|||||||
* exports (dumps) var, in more printable design, but without detail info
|
* exports (dumps) var, in more printable design, but without detail info
|
||||||
*
|
*
|
||||||
* @param mixed $data Anything
|
* @param mixed $data Anything
|
||||||
* @param bool $no_html If true true do not add <pre> tags
|
* @param bool $no_html [=false] If true true do not add <pre> tags
|
||||||
* @return string A text string
|
* @return string A text string
|
||||||
*/
|
*/
|
||||||
public static function exportVar(mixed $data, bool $no_html = false): string
|
public static function exportVar(mixed $data, bool $no_html = false): string
|
||||||
@@ -217,7 +217,7 @@ class Support
|
|||||||
* Return file name and line number where this was called
|
* Return file name and line number where this was called
|
||||||
* One level up
|
* One level up
|
||||||
*
|
*
|
||||||
* @param int $level trace level, default 1
|
* @param int $level [=1] trace level
|
||||||
* @return string|null null or file name:line number
|
* @return string|null null or file name:line number
|
||||||
*/
|
*/
|
||||||
public static function getCallerFileLine(int $level = 1): ?string
|
public static function getCallerFileLine(int $level = 1): ?string
|
||||||
@@ -238,14 +238,14 @@ class Support
|
|||||||
* eg for debugging, this function does this
|
* eg for debugging, this function does this
|
||||||
*
|
*
|
||||||
* call this method in the child method and you get the parent function that called
|
* call this method in the child method and you get the parent function that called
|
||||||
* @param int $level trace level, default 1
|
* @param int $level [=1] trace level
|
||||||
* @return ?string null or the function that called the function
|
* @return string|null null or the function that called the function
|
||||||
* where this method is called
|
* where this method is called
|
||||||
*/
|
*/
|
||||||
public static function getCallerMethod(int $level = 1): ?string
|
public static function getCallerMethod(int $level = 1): ?string
|
||||||
{
|
{
|
||||||
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
// print \CoreLibs\Debug\Support::printAr($traces);
|
// print "getCallerMethod:<br>" . \CoreLibs\Debug\Support::printAr($traces);
|
||||||
// We should check from top down if unset?
|
// We should check from top down if unset?
|
||||||
// sets the start point here, and in level two (the sub call) we find this
|
// sets the start point here, and in level two (the sub call) we find this
|
||||||
if (isset($traces[$level])) {
|
if (isset($traces[$level])) {
|
||||||
@@ -254,6 +254,41 @@ class Support
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the class that first called it and skip the base class
|
||||||
|
* Companion method to getCallerMethod
|
||||||
|
*
|
||||||
|
* @param int $level [=1] trace level
|
||||||
|
* @return ?string null if class not found
|
||||||
|
*/
|
||||||
|
public static function getCallerClass(int $level = 1): ?string
|
||||||
|
{
|
||||||
|
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
// print "getCallerClass:<br>" . \CoreLibs\Debug\Support::printAr($traces);
|
||||||
|
if (isset($traces[$level])) {
|
||||||
|
return $traces[$level]['class'] ?? null;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns class and method together
|
||||||
|
*
|
||||||
|
* @param int $level [=1] travel level
|
||||||
|
* @return string|null null if trace level not found, else namespace class and method
|
||||||
|
*/
|
||||||
|
public static function getCallerClassMethod(int $level = 1): ?string
|
||||||
|
{
|
||||||
|
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
// print "getCallerClass:<br>" . \CoreLibs\Debug\Support::printAr($traces);
|
||||||
|
if (isset($traces[$level])) {
|
||||||
|
return ($traces[$level]['class'] ?? '-')
|
||||||
|
. ($traces[$level]['type'] ?? '')
|
||||||
|
. $traces[$level]['function'];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns array with all methods in the call stack in the order so that last
|
* Returns array with all methods in the call stack in the order so that last
|
||||||
* called is last in order
|
* called is last in order
|
||||||
@@ -283,25 +318,21 @@ class Support
|
|||||||
* Is mostly used in debug log statements to get the class where the debug
|
* Is mostly used in debug log statements to get the class where the debug
|
||||||
* was called
|
* was called
|
||||||
* gets top level class
|
* gets top level class
|
||||||
* loops over the debug backtrace until if finds the first class (from the end)
|
* loops over the debug backtrace until if finds the first class (from the end)
|
||||||
*
|
*
|
||||||
* @return string Class name with namespace
|
* @return string Class name with namespace
|
||||||
*/
|
*/
|
||||||
public static function getCallerClass(): string
|
public static function getCallerTopLevelClass(): string
|
||||||
{
|
{
|
||||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
// ?? [['class' => get_called_class()]];
|
// print "getCallerClass:<br>" . \CoreLibs\Debug\Support::printAr($traces);
|
||||||
// TODO make sure that this doesn't loop forver
|
|
||||||
$class = null;
|
$class = null;
|
||||||
while ($class === null && count($backtrace) > 0) {
|
// reverse and stop at first set class, this is the top level one
|
||||||
// if current is
|
foreach (array_reverse($traces) as $trace) {
|
||||||
// [function] => debug
|
$class = $trace['class'] ?? null;
|
||||||
// [class] => CoreLibs\Debug\Logging
|
if (!empty($class)) {
|
||||||
// then return
|
break;
|
||||||
// (OUTSIDE) because it was not called from a class method
|
}
|
||||||
// or return file name
|
|
||||||
$get_class = array_pop($backtrace);
|
|
||||||
$class = $get_class['class'] ?? null;
|
|
||||||
}
|
}
|
||||||
// on null or empty return empty string
|
// on null or empty return empty string
|
||||||
return empty($class) ? '' : $class;
|
return empty($class) ? '' : $class;
|
||||||
|
|||||||
@@ -381,7 +381,7 @@ class Logging
|
|||||||
// auto set (should be deprecated in future)
|
// auto set (should be deprecated in future)
|
||||||
$this->setLogFileId(
|
$this->setLogFileId(
|
||||||
str_replace(':', '-', $this->host_name) . '_'
|
str_replace(':', '-', $this->host_name) . '_'
|
||||||
. str_replace('\\', '-', Support::getCallerClass())
|
. str_replace('\\', '-', Support::getCallerTopLevelClass())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (empty($this->getLogFileId())) {
|
if (empty($this->getLogFileId())) {
|
||||||
@@ -460,7 +460,7 @@ class Logging
|
|||||||
// set per class, but don't use get_class as we will only get self
|
// set per class, but don't use get_class as we will only get self
|
||||||
$rpl_string = !$this->getLogFlag(Flag::per_class) ? '' : '_'
|
$rpl_string = !$this->getLogFlag(Flag::per_class) ? '' : '_'
|
||||||
// set sub class settings
|
// set sub class settings
|
||||||
. str_replace('\\', '-', Support::getCallerClass());
|
. str_replace('\\', '-', Support::getCallerTopLevelClass());
|
||||||
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
|
$fn = str_replace('{CLASS}', $rpl_string, $fn); // create output filename
|
||||||
|
|
||||||
// if request to write to one file
|
// if request to write to one file
|
||||||
@@ -526,7 +526,10 @@ class Logging
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare the log message with all needed info blocks:
|
* Prepare the log message with all needed info blocks:
|
||||||
* [timestamp] [host name] [file path + file] [running uid] {class} <debug level/group id> - message
|
* [timestamp] [host name] [file path + file::row number] [running uid] {class::/->method}
|
||||||
|
* <debug level:debug group id> - message
|
||||||
|
* Note: group id is only for debug level
|
||||||
|
* if no method can be found or no class is found a - will be wirtten
|
||||||
*
|
*
|
||||||
* @param Level $level Log level we will write to
|
* @param Level $level Log level we will write to
|
||||||
* @param string|Stringable $message The message to write
|
* @param string|Stringable $message The message to write
|
||||||
@@ -545,16 +548,32 @@ class Logging
|
|||||||
if (!$this->checkLogLevel($level)) {
|
if (!$this->checkLogLevel($level)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
$file_line = '';
|
||||||
|
$caller_class_method = '-';
|
||||||
|
$traces = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
// print "[" . $level->getName() . "] [$message] prepareLog:<br>" . Support::printAr($traces);
|
||||||
// file + line: call not this but one before (the one that calls this)
|
// file + line: call not this but one before (the one that calls this)
|
||||||
$file_line = Support::getCallerFileLine(2) ??
|
// start from this level, if unset fall down until we are at null
|
||||||
System::getPageName(System::FULL_PATH);
|
$start_trace_level = 2;
|
||||||
// get the last class entry and wrie that
|
for ($trace_level = $start_trace_level; $trace_level >= 0; $trace_level--) {
|
||||||
$class = Support::getCallerClass();
|
if (isset($traces[$trace_level])) {
|
||||||
// method/function: prepareLog->(debug|info|...)->[THIS]
|
$file_line = ($traces[$trace_level]['file'] ?? $traces[$trace_level]['function'])
|
||||||
$method = Support::getCallerMethod(3);
|
. ':' . ($traces[$trace_level]['line'] ?? '-');
|
||||||
if ($method !== null) {
|
// as namespace\class->method
|
||||||
$class .= '::' . $method;
|
$caller_class_method =
|
||||||
|
// get the last call before we are in the Logging class
|
||||||
|
($traces[$trace_level]['class'] ?? '')
|
||||||
|
// connector, if unkown use ==
|
||||||
|
. ($traces[$trace_level]['type'] ?? '')
|
||||||
|
// method/function: prepareLog->(debug|info|...)->[THIS]
|
||||||
|
. $traces[$trace_level]['function'];
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (empty($file_line)) {
|
||||||
|
$file_line = System::getPageName(System::FULL_PATH);
|
||||||
|
}
|
||||||
|
// print "CLASS: " . $class . "<br>";
|
||||||
// get timestamp
|
// get timestamp
|
||||||
$timestamp = Support::printTime();
|
$timestamp = Support::printTime();
|
||||||
|
|
||||||
@@ -574,7 +593,7 @@ class Logging
|
|||||||
. '[' . $this->host_name . '] '
|
. '[' . $this->host_name . '] '
|
||||||
. '[' . $file_line . '] '
|
. '[' . $file_line . '] '
|
||||||
. '[' . $this->running_uid . '] '
|
. '[' . $this->running_uid . '] '
|
||||||
. '{' . $class . '} '
|
. '{' . $caller_class_method . '} '
|
||||||
. '<' . strtoupper($group_str) . '> '
|
. '<' . strtoupper($group_str) . '> '
|
||||||
. $message
|
. $message
|
||||||
. $context_str;
|
. $context_str;
|
||||||
|
|||||||
@@ -562,10 +562,10 @@ final class CoreLibsDebugSupportTest extends TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* test the lowest one (one above base)
|
||||||
*
|
*
|
||||||
* @cover ::getCallerClass
|
* @cover ::getCallerClass
|
||||||
* @testWith ["PHPUnit\\TextUI\\Command"]
|
* @testWith ["tests\\CoreLibsDebugSupportTest"]
|
||||||
* @testdox getCallerClass check if it returns $expected [$_dataName]
|
* @testdox getCallerClass check if it returns $expected [$_dataName]
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
@@ -578,6 +578,40 @@ final class CoreLibsDebugSupportTest extends TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test highest return (top level)
|
||||||
|
*
|
||||||
|
* @cover ::getCallerTopLevelClass
|
||||||
|
* @testWith ["PHPUnit\\TextUI\\Command"]
|
||||||
|
* @testdox getCallerTopLevelClass check if it returns $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testGetCallerTopLevelClass(string $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
Support::getCallerTopLevelClass()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test highest return (top level)
|
||||||
|
*
|
||||||
|
* @cover ::getCallerClassMethod
|
||||||
|
* @testWith ["tests\\CoreLibsDebugSupportTest->testGetCallerClassMethod"]
|
||||||
|
* @testdox getCallerClassMethod check if it returns $expected [$_dataName]
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testGetCallerClassMethod(string $expected): void
|
||||||
|
{
|
||||||
|
$this->assertEquals(
|
||||||
|
$expected,
|
||||||
|
Support::getCallerClassMethod()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ final class CoreLibsLoggingLoggingTest extends TestCase
|
|||||||
. "\[[\w\.]+(:\d+)?\]\s{1}" // host:port
|
. "\[[\w\.]+(:\d+)?\]\s{1}" // host:port
|
||||||
. "\[[\w\-\.\/]+:\d+\]\s{1}" // folder/file
|
. "\[[\w\-\.\/]+:\d+\]\s{1}" // folder/file
|
||||||
. "\[\w+\]\s{1}" // run id
|
. "\[\w+\]\s{1}" // run id
|
||||||
. "{[\w\\\\]+(::\w+)?}\s{1}"; // class
|
. "{[\w\\\\]+((::|->)\w+)?}\s{1}"; // class
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void
|
public static function tearDownAfterClass(): void
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user