Improved backtracing

This commit is contained in:
Netkas 2022-12-31 01:23:30 -05:00
parent 09141f3d10
commit cdf3eae890
7 changed files with 192 additions and 90 deletions

View file

@ -108,15 +108,14 @@
if(Validate::checkLevelType(LevelType::Verbose, Log::getRuntimeOptions()->getLogLevel()))
{
$backtrace_output = Utilities::parseBacktrace($event);
$backtrace_output = Utilities::getTraceString($event, Log::getRuntimeOptions()->isDisplayAnsi());
print(sprintf(
"%s [%s] [%s] (%s) - %s" . PHP_EOL,
"%s [%s] [%s] %s %s" . PHP_EOL,
$event->getTimestamp(),
self::formatAppColor($options->getApplicationName()),
self::colorize($event, $event->Level),
$backtrace_output !== null ? $backtrace_output : 'λ',
$event->Message
$backtrace_output, $event->Message
));
if($event->Exception !== null)
@ -126,7 +125,7 @@
}
print(sprintf(
"%s [%s] [%s] - %s" . PHP_EOL,
"%s [%s] [%s] %s" . PHP_EOL,
$event->getTimestamp(),
self::formatAppColor($options->getApplicationName()),
self::colorize($event, $event->Level),

View file

@ -21,14 +21,11 @@
*/
public static function out(Options $options, Event $event, ?FileHandle $fileHandle=null): void
{
$backtrace_output = Utilities::parseBacktrace($event);
$backtrace_output = Utilities::getTraceString($event);
$handle = $fileHandle ?? $options->getFileHandle();
switch($event->Level)
{
// Only process Debug/Verbose events if the log level is set to Debug/Verbose
// otherwise omit it because it could be a performance hit if there are a lot of
// debug/verbose events being logged.
case LevelType::Debug:
case LevelType::Verbose:
if(!Validate::checkLevelType($event->Level, Log::getRuntimeOptions()->getLogLevel()))
@ -40,7 +37,7 @@
}
$handle->fwrite(sprintf(
"%s [%s] [%s] (%s) - %s" . PHP_EOL,
"%s [%s] [%s] (%s) %s" . PHP_EOL,
$event->getTimestamp(),
$options->getApplicationName(),
Utilities::levelToString($event->Level),

View file

@ -6,17 +6,16 @@
use LogLib\Objects\Backtrace;
use LogLib\Objects\Event;
use OptsLib\Parse;
use Properties\Prop;
use Throwable;
class Utilities
{
/**
* Returns the current backtrace
*
* @return Backtrace[]
* @param bool $full
* @return array
*/
public static function getBacktrace(): array
public static function getBacktrace(bool $full=false): array
{
if(!function_exists('debug_backtrace'))
return [];
@ -26,31 +25,10 @@
foreach($backtrace as $trace)
{
$results[] = Prop::fromArray($trace);
}
if(isset($trace['class'] ) && str_contains($trace['class'], 'LogLib') && !$full)
continue;
return $results;
}
/**
* @param Throwable $e
* @return array
*/
public static function exceptionToArray(Throwable $e): array
{
$results = [
'hash' => spl_object_hash($e),
'type' => get_class($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTrace(),
];
if($e->getPrevious() !== null)
{
$results['previous'] = self::exceptionToArray($e->getPrevious());
$results[] = new Backtrace($trace);
}
return $results;
@ -124,6 +102,7 @@
case 'vrb':
return LevelType::Verbose;
default:
case LevelType::Info:
case 'info':
case '4':
@ -153,9 +132,6 @@
case '0':
case 'sil':
return LevelType::Silent;
default:
return LevelType::Info;
}
}
@ -202,46 +178,6 @@
return date('Y-m-d') . '.log';
}
/**
* Returns the formatted backtrace
*
* @param Event $event
* @return string|null
*/
public static function parseBacktrace(Event $event): ?string
{
$backtrace = null;
if ($event->Backtrace !== null && count($event->Backtrace) > 0)
{
foreach ($event->Backtrace as $item)
{
if ($item->Class !== 'LogLib\\Log')
{
$backtrace = $item;
break;
}
}
}
$backtrace_output = null;
if ($backtrace !== null)
{
if ($backtrace->Class !== null)
{
$backtrace_output = $backtrace->Class . $backtrace->Type . $backtrace->Function . '()';
}
else
{
$backtrace_output = $backtrace->Function . '()';
}
if ($backtrace->Line !== null)
$backtrace_output .= ':' . $backtrace->Line;
}
return $backtrace_output;
}
/**
* Returns a random string of characters
*
@ -260,4 +196,31 @@
return $randomString;
}
/**
* @param Event $event
* @param bool $ansi
* @return string|null
*/
public static function getTraceString(Event $event, bool $ansi=false): ?string
{
if($event->getBacktrace() == null)
return 'λ';
$backtrace = $event->getBacktrace()[0];
$function = $backtrace->getFunction();
$class = $backtrace->getClass();
if($ansi)
{
$function = "\033[1;37m$function\033[0m";
$class = "\033[1;37m$class\033[0m";
}
if($class == null)
return "{$function}()";
$type = ($backtrace->getType() == '->' ? '->' : '::');
return "{$class}{$type}{$function}()";
}
}

View file

@ -8,10 +8,12 @@
use LogLib\Abstracts\LevelType;
use LogLib\Classes\Console;
use LogLib\Classes\FileLogging;
use LogLib\Classes\Utilities;
use LogLib\Classes\Validate;
use LogLib\Objects\Event;
use LogLib\Objects\Options;
use LogLib\Objects\RuntimeOptions;
use Properties\Exceptions\ReconstructException;
use Throwable;
class Log
@ -97,6 +99,7 @@
* @param string|null $message The message of the event
* @param Throwable|null $throwable The exception that was thrown, if any
* @return void
* @throws ReconstructException
*/
private static function log(string $application_name, string $level=LevelType::Info, ?string $message=null, ?Throwable $throwable=null): void
{
@ -115,6 +118,9 @@
$event->Message = $message;
$event->Exception = $throwable;
if($event->getBacktrace() == null)
$event->setBacktrace(Utilities::getBacktrace());
if(self::getRuntimeOptions()->isConsoleOutput())
Console::out($application, $event);

View file

@ -12,7 +12,7 @@
* @var string|null
* @property_name function
*/
public $Function;
private $Function;
/**
* The line number of the backtrace
@ -20,7 +20,7 @@
* @var int|null
* @property_name line
*/
public $Line;
private $Line;
/**
* The file name of the backtrace
@ -28,7 +28,7 @@
* @var string|null
* @property_name file
*/
public $File;
private $File;
/**
* The class name, if any, of the backtrace
@ -36,7 +36,7 @@
* @var string|null
* @property_name class
*/
public $Class;
private $Class;
/**
* The current call type. If a method call, "->" is returned.
@ -47,7 +47,7 @@
* @var string|null
* @property_name type
*/
public $Type;
private $Type;
/**
* If inside a function, this lists the functions arguments. If inside
@ -56,5 +56,119 @@
* @var array|null
* @property_name args
*/
public $Args;
private $Args;
/**
* Public Constructor
*
* @param array|null $backtrace
*/
public function __construct(?array $backtrace=null)
{
if($backtrace === null)
return;
$this->Function = $backtrace['function'] ?? null;
$this->Line = $backtrace['line'] ?? null;
$this->File = $backtrace['file'] ?? null;
$this->Class = $backtrace['class'] ?? null;
$this->Type = $backtrace['type'] ?? null;
$this->Args = $backtrace['args'] ?? null;
}
/**
* @return string|null
*/
public function getFunction(): ?string
{
return $this->Function;
}
/**
* @param string|null $Function
*/
public function setFunction(?string $Function): void
{
$this->Function = $Function;
}
/**
* @return int|null
*/
public function getLine(): ?int
{
return $this->Line;
}
/**
* @param int|null $Line
*/
public function setLine(?int $Line): void
{
$this->Line = $Line;
}
/**
* @return string|null
*/
public function getFile(): ?string
{
return $this->File;
}
/**
* @param string|null $File
*/
public function setFile(?string $File): void
{
$this->File = $File;
}
/**
* @return string|null
*/
public function getClass(): ?string
{
return $this->Class;
}
/**
* @param string|null $Class
*/
public function setClass(?string $Class): void
{
$this->Class = $Class;
}
/**
* @return string|null
*/
public function getType(): ?string
{
return $this->Type;
}
/**
* @param string|null $Type
*/
public function setType(?string $Type): void
{
$this->Type = $Type;
}
/**
* @return array|null
*/
public function getArgs(): ?array
{
return $this->Args;
}
/**
* @param array|null $Args
*/
public function setArgs(?array $Args): void
{
$this->Args = $Args;
}
}

View file

@ -7,7 +7,6 @@
use LogLib\Abstracts\LevelType;
use LogLib\Classes\Utilities;
use Throwable;
class Event
{
/**
@ -33,7 +32,7 @@
* @var Backtrace[]|null
* @property_name backtrace
*/
public $Backtrace;
private $Backtrace;
/**
* The exception that was thrown, if any
@ -53,7 +52,7 @@
public function __construct()
{
$this->Timestamp = date('Y-m-dTH:i:s.v') . (date('p') == 'Z' ? 'Z' : 'L');
$this->Timestamp = date('c');
}
/**
@ -75,4 +74,20 @@
return $this->Timestamp;
}
/**
* @return array|null
*/
public function getBacktrace(): ?array
{
return $this->Backtrace;
}
/**
* @param array|null $Backtrace
*/
public function setBacktrace(?array $Backtrace): void
{
$this->Backtrace = $Backtrace;
}
}

8
tests/test_backtrace.php Normal file
View file

@ -0,0 +1,8 @@
<?php
require('ncc');
import('net.nosial.loglib', 'latest');
var_dump(\LogLib\Classes\Utilities::getBacktrace(true));