Fix logging line and call method information

The logging line number and file was for the previous call position, not for
where the actual log entry was called

Also fix for ErrorMessage class calls with shifting the start position up depending on which method is called.

Output shows file and line where the message/log call was done and the function/class method where the log call was done
This commit is contained in:
Clemens Schwaighofer
2025-11-27 17:54:28 +09:00
parent 8af71b70a3
commit e473e7899d
8 changed files with 149 additions and 34 deletions

View File

@@ -58,6 +58,14 @@ $em->setErrorMsg('100-2', 'error', 'Input wring', jump_target:['target' => 'foo-
$em->setMessage('error', 'I have no id set', jump_target:['target' => 'bar-123', 'info' => 'Jump Bar']);
$em->setMessage('error', 'Jump empty', jump_target:['target' => 'bar-empty']);
function inLine(\CoreLibs\Logging\ErrorMessage $em): void
{
$em->log->error('Direct log before from ', context:['function' => __FUNCTION__]);
$em->setMessage('error', 'Inline call', context:['test' => 'inLine Function']);
$em->log->error('Direct log from ', context:['function' => __FUNCTION__]);
}
inLine($em);
print "ErrorsLast: <pre>" . $log->prAr($em->getLastErrorMsg()) . "</pre>";
print "ErrorsIds: <pre>" . $log->prAr($em->getErrorIds()) . "</pre>";
print "Errors: <pre>" . $log->prAr($em->getErrorMsg()) . "</pre>";

View File

@@ -121,6 +121,12 @@ Class TestP
public function test(): void
{
$this->log->info('TestL::test call');
$this->subCall();
}
public function subCall(): void
{
$this->log->info('TestL::sub_call call');
}
}

View File

@@ -46,10 +46,15 @@ function runFunctionArgsArray(name, args) {
fn.apply(window, args);
}
function isObject(val) {
if (val === null) {
return false;
}
return typeof val === "function" || typeof val === "object";
return val !== null && typeof val === "object" && !Array.isArray(val);
}
function isArray(val) {
return val !== null && Array.isArray(val);
}
function isIterable(val) {
if (val == null) return false;
if (typeof val[Symbol.iterator] === "function" && typeof val !== "string") return true;
return typeof val === "object" && val.constructor === Object;
}
function getObjectCount(object) {
if (!isObject(object)) {
@@ -158,7 +163,7 @@ var HtmlElementCreator = class {
if (base.id == id) {
base.sub.push(deepCopyFunction(attach));
} else {
if (isObject(base.sub) && base.sub.length > 0) {
if (isArray(base.sub) && base.sub.length > 0) {
for (var i = 0; i < base.sub.length; i++) {
this.ael(base.sub[i], attach, id);
}
@@ -297,7 +302,7 @@ var HtmlElementCreator = class {
line += ' name="' + (tree.name ? tree.name : tree.id) + '"';
}
}
if (isObject(tree.css) && tree.css.length > 0) {
if (isArray(tree.css) && tree.css.length > 0) {
line += ' class="';
for (i = 0; i < tree.css.length; i++) {
line += tree.css[i] + " ";
@@ -314,7 +319,7 @@ var HtmlElementCreator = class {
}
line += ">";
content.push(line);
if (isObject(tree.sub) && tree.sub.length > 0) {
if (isArray(tree.sub) && tree.sub.length > 0) {
if (tree.content) {
content.push(tree.content);
}
@@ -1331,6 +1336,17 @@ var LoginNavMenu = class {
}
};
// src/utils/BrowserDetect.mjs
function isWebkit() {
return "GestureEvent" in window;
}
function isMobileWebKit() {
return "ongesturechange" in window;
}
function isDesktopWebKit() {
return typeof window !== "undefined" && "safari" in window && "pushNotification" in window.safari;
}
// src/utils.mjs
var aiob = new ActionIndicatorOverlayBox();
var hec = new HtmlElementCreator();
@@ -1433,6 +1449,12 @@ function executeFunctionByName2(functionName, context) {
function isObject2(val) {
return isObject(val);
}
function isArray2(val) {
return isArray(val);
}
function isIterable2(val) {
return isIterable(val);
}
function getObjectCount2(object) {
return getObjectCount(object);
}
@@ -1613,3 +1635,12 @@ function createActionBox(target_id = "actionBox", title = "", contents = {}, hea
function adjustActionBoxHeight(target_id = "actionBox", override = 0, content_override = 0) {
ab.adjustActionBoxHeight(target_id, override, content_override);
}
function isWebkit2() {
return isWebkit();
}
function isMobileWebKit2() {
return isMobileWebKit();
}
function isDesktopWebKit2() {
return isDesktopWebKit();
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -77,7 +77,7 @@ class Byte
// labels in order of size [Y, Z]
$labels = ['', 'K', 'M', 'G', 'T', 'P', 'E'];
// exp position calculation
$exp = floor(log($abs_bytes, $unit));
$exp = (int)floor(log($abs_bytes, $unit));
// avoid printing out anything larger than max labels
if ($exp >= count($labels)) {
$exp = count($labels) - 1;

View File

@@ -131,6 +131,7 @@ class ErrorMessage
// set a jump target
$this->setJumpTarget($jump_target['target'] ?? null, $jump_target['info'] ?? null, $level);
// write to log for abort/crash
$this->log->setErrorMessageCallSetErrorMsg();
switch ($level) {
case 'notice':
$this->log->notice($message ?? $str, array_merge([
@@ -210,6 +211,7 @@ class ErrorMessage
?bool $log_error = null,
?bool $log_warning = null,
): void {
$this->log->setErrorMessageCallSetMessage();
$this->setErrorMsg(
$error_id ?? '',
$level,

View File

@@ -29,11 +29,19 @@ use Stringable;
class Logging
{
/** @var int minimum size for a max file size, so we don't set 1 byte, 10kb */
public const MIN_LOG_MAX_FILESIZE = 10 * 1024;
public const int MIN_LOG_MAX_FILESIZE = 10 * 1024;
/** @var string log file extension, not changeable */
private const LOG_FILE_NAME_EXT = "log";
private const string LOG_FILE_NAME_EXT = "log";
/** @var string log file block separator, not changeable */
private const LOG_FILE_BLOCK_SEPARATOR = '.';
private const string LOG_FILE_BLOCK_SEPARATOR = '.';
/** @var int the base stack trace level for the line number */
private const int DEFAULT_STACK_TRACE_LEVEL_LINE = 1;
/** @var array<string,int> */
private const array STACK_OVERRIDE_CHECK = [
'setErrorMsg' => 2,
'setMessage' => 3,
];
// MARK: OPTION array
// NOTE: the second party array{} hs some errors
@@ -138,6 +146,12 @@ class Logging
/** @var string Y-m-d file in file name */
private string $log_file_date = '';
// speical flags for ErrorMessage calls
/** @var bool Flag to set if called from ErrorMessage::setErrorMsg */
private bool $error_message_call_set_error_msg = false;
/** @var bool Flag to set if called from ErrorMessage::setMessage */
private bool $error_message_call_set_message = false;
/**
* 1: create a new log file per run (time stamp + unique ID)
* 2: add Y-m-d and do automatic daily rotation
@@ -627,25 +641,55 @@ class Logging
$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)
// start from this level, if unset fall down until we are at null
$start_trace_level = 2;
for ($trace_level = $start_trace_level; $trace_level >= 0; $trace_level--) {
if (isset($traces[$trace_level])) {
$file_line = ($traces[$trace_level]['file'] ?? $traces[$trace_level]['function'])
. ':' . ($traces[$trace_level]['line'] ?? '-');
// as namespace\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;
$stack_trace_start_level_line = self::DEFAULT_STACK_TRACE_LEVEL_LINE;
// set stack trace level +1 if called from ErrorMessage::setMessage
if ($this->error_message_call_set_message) {
$stack_trace_start_level_line = 3;
} elseif ($this->error_message_call_set_error_msg) {
$stack_trace_start_level_line = 2;
}
// if we have line > default, then check if valid, else reset to default
if ($stack_trace_start_level_line > self::DEFAULT_STACK_TRACE_LEVEL_LINE) {
// check if function at level is one of the override checks
$fn_check = $traces[$stack_trace_start_level_line]['function'] ?? '';
if (
!isset(self::STACK_OVERRIDE_CHECK[$fn_check]) ||
self::STACK_OVERRIDE_CHECK[$fn_check] != $stack_trace_start_level_line
) {
$stack_trace_start_level_line = self::DEFAULT_STACK_TRACE_LEVEL_LINE;
}
}
$this->error_message_call_set_message = false;
$this->error_message_call_set_error_msg = false;
// set stack trace level +1 if called from ErrorMessage::setMessage
// print "[" . $level->getName() . "] [$message] [" . $stack_trace_start_level_line . "] "
// . "prepareLog:<br>" . Support::printAr($traces);
// file + line: call not this but one before (the one that calls this)
// start from this level, if unset fall down until we are at null
// NOTE this has to be pushed to 3 for setMessage wrap calls
for ($trace_level = $stack_trace_start_level_line; $trace_level >= 0; $trace_level--) {
if (!isset($traces[$trace_level])) {
continue;
}
$file_line = ($traces[$trace_level]['file'] ?? $traces[$trace_level]['function'])
. ':' . ($traces[$trace_level]['line'] ?? '-');
// call function is one stack level above
$trace_level++;
// skip setting if we are in the top level already
if (!isset($traces[$trace_level])) {
break;
}
// as namespace\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 not line is set
if (empty($file_line)) {
$file_line = System::getPageName(System::FULL_PATH);
}
@@ -1017,6 +1061,30 @@ class Logging
return $this->log_max_filesize;
}
// *********************************************************************
// MARK: ErrorMessage class overrides
// *********************************************************************
/**
* call if called from Error Message setMessage wrapper
*
* @return void
*/
public function setErrorMessageCallSetMessage(): void
{
$this->error_message_call_set_message = true;
}
/**
* call if called from Error Message setMessage wrapper
*
* @return void
*/
public function setErrorMessageCallSetErrorMsg(): void
{
$this->error_message_call_set_error_msg = true;
}
// *********************************************************************
// MARK: OPTIONS CALLS
// *********************************************************************