36    protected bool $logDebug;
 
   38    private string $format = TextFormat::AQUA . 
"[%s] " . TextFormat::RESET . 
"%s[%s/%s]: %s" . TextFormat::RESET;
 
   39    private bool $useFormattingCodes = 
false;
 
   40    private string $mainThreadName;
 
   41    private string $timezone;
 
   47    public function __construct(?
string $logFile, 
bool $useFormattingCodes, 
string $mainThreadName, \DateTimeZone $timezone, 
bool $logDebug = 
false, ?
string $logArchiveDir = 
null){
 
   48        parent::__construct();
 
   49        $this->logDebug = $logDebug;
 
   51        $this->useFormattingCodes = $useFormattingCodes;
 
   52        $this->mainThreadName = $mainThreadName;
 
   53        $this->timezone = $timezone->getName();
 
   55        if($logFile !== 
null){
 
   57            $this->logWriterThread->start(NativeThread::INHERIT_NONE);
 
 
   80        $this->format = $format;
 
 
   84        $this->send($message, \LogLevel::EMERGENCY, 
"EMERGENCY", TextFormat::RED);
 
 
   87    public function alert($message){
 
   88        $this->send($message, \LogLevel::ALERT, 
"ALERT", TextFormat::RED);
 
 
   92        $this->send($message, \LogLevel::CRITICAL, 
"CRITICAL", TextFormat::RED);
 
 
   95    public function error($message){
 
   96        $this->send($message, \LogLevel::ERROR, 
"ERROR", TextFormat::DARK_RED);
 
 
  100        $this->send($message, \LogLevel::WARNING, 
"WARNING", TextFormat::YELLOW);
 
 
  104        $this->send($message, \LogLevel::NOTICE, 
"NOTICE", TextFormat::AQUA);
 
 
  107    public function info($message){
 
  108        $this->send($message, \LogLevel::INFO, 
"INFO", TextFormat::WHITE);
 
 
  111    public function debug($message, 
bool $force = 
false){
 
  112        if(!$this->logDebug && !$force){
 
  115        $this->send($message, \LogLevel::DEBUG, 
"DEBUG", TextFormat::GRAY);
 
  118    public function setLogDebug(
bool $logDebug) : void{
 
  119        $this->logDebug = $logDebug;
 
  129        $this->critical(implode(
"\n", Utils::printableExceptionInfo($e, $trace)));
 
  131        $this->syncFlushBuffer();
 
 
  134    public function log($level, $message){
 
  136            case \LogLevel::EMERGENCY:
 
  137                $this->emergency($message);
 
  139            case \LogLevel::ALERT:
 
  140                $this->alert($message);
 
  142            case \LogLevel::CRITICAL:
 
  143                $this->critical($message);
 
  145            case \LogLevel::ERROR:
 
  146                $this->error($message);
 
  148            case \LogLevel::WARNING:
 
  149                $this->warning($message);
 
  151            case \LogLevel::NOTICE:
 
  152                $this->notice($message);
 
  154            case \LogLevel::INFO:
 
  155                $this->info($message);
 
  157            case \LogLevel::DEBUG:
 
  158                $this->debug($message);
 
 
  166    public function buffer(\Closure $c) : void{
 
  167        $this->synchronized($c);
 
 
  170    public function shutdownLogWriterThread() : void{
 
  171        if($this->logWriterThread !== null){
 
  172            if(NativeThread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
 
  173                $this->logWriterThread->shutdown();
 
  175                throw new \LogicException(
"Only the creator thread can shutdown the logger thread");
 
  180    protected function send(
string $message, 
string $level, 
string $prefix, 
string $color) : void{
 
  181        $time = new \DateTime(
'now', new \DateTimeZone($this->timezone));
 
  183        $thread = NativeThread::getCurrentThread();
 
  184        if($thread === 
null){
 
  185            $threadName = $this->mainThreadName . 
" thread";
 
  186        }elseif($thread instanceof Thread || $thread instanceof Worker){
 
  187            $threadName = $thread->getThreadName() . 
" thread";
 
  189            $threadName = (new \ReflectionClass($thread))->getShortName() . 
" thread";
 
  192        $message = sprintf($this->format, $time->format(
"H:i:s.v"), $color, $threadName, $prefix, TextFormat::addBase($color, TextFormat::clean($message, 
false)));
 
  194        if(!Terminal::isInit()){
 
  195            Terminal::init($this->useFormattingCodes); 
 
  198        $this->
synchronized(
function() use ($message, $level, $time) : void{
 
  199            Terminal::writeLine($message);
 
  200            if($this->logWriterThread !== 
null){
 
  201                $this->logWriterThread->write($time->format(
"Y-m-d") . 
" " . TextFormat::clean($message) . PHP_EOL);
 
  207            foreach($this->attachments as $attachment){
 
  208                $attachment->log($level, $message);
 
  213    public function syncFlushBuffer() : void{
 
  214        $this->logWriterThread?->syncFlushBuffer();
 
  217    public function __destruct(){
 
  218        if($this->logWriterThread !== 
null && !$this->logWriterThread->isJoined() && NativeThread::getCurrentThreadId() === $this->logWriterThread->getCreatorId()){
 
  219            $this->shutdownLogWriterThread();
 
 
setFormat(string $format)
__construct(?string $logFile, bool $useFormattingCodes, string $mainThreadName, \DateTimeZone $timezone, bool $logDebug=false, ?string $logArchiveDir=null)
logException(\Throwable $e, $trace=null)