Advertisement
daniellz

Untitled

Feb 26th, 2025
199
0
6 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.27 KB | None | 0 0
  1. <?php
  2. declare(strict_types=1);
  3.  
  4. namespace app\services\Log;
  5.  
  6. use Psr\Http\Message\ResponseInterface;
  7. use Psr\Log\LogLevel;
  8.  
  9. /**
  10.  * Debug console logger that outputs formatted logs directly to console
  11.  * Useful for live debugging in production environments without modifying log files
  12.  */
  13. class DebugConsoleLogger extends LoggerService
  14. {
  15.     // ANSI color codes for console output
  16.     private const COLORS = [
  17.         LogLevel::ERROR => "\033[31m", // Red
  18.         LogLevel::WARNING => "\033[33m", // Yellow
  19.         LogLevel::INFO => "\033[32m", // Green
  20.         LogLevel::DEBUG => "\033[36m", // Cyan
  21.         'reset' => "\033[0m", // Reset
  22.         'bold' => "\033[1m", // Bold
  23.         'dim' => "\033[2m", // Dim
  24.     ];
  25.    
  26.     /**
  27.      * Format and output log message to console
  28.      */
  29.     public function log($level, LogChannels $channel, $message, array $context = [], ?\Throwable $e = null, ?ResponseInterface $response = null): void
  30.     {
  31.         // Add exception and response to context if provided
  32.         if ($e) {
  33.             $context['exception'] = [
  34.                 'class' => get_class($e),
  35.                 'message' => $e->getMessage(),
  36.                 'code' => $e->getCode(),
  37.                 'file' => $e->getFile() . ':' . $e->getLine(),
  38.                 'trace' => $this->formatTrace($e->getTraceAsString())
  39.             ];
  40.         }
  41.        
  42.         if ($response) {
  43.             $context['response'] = [
  44.                 'status' => $response->getStatusCode(),
  45.                 'reason' => $response->getReasonPhrase(),
  46.                 'body' => $this->truncateResponseBody((string)$response->getBody())
  47.             ];
  48.         }
  49.        
  50.         // Format the output
  51.         $timestamp = (new \DateTimeImmutable())->format('Y-m-d H:i:s.u');
  52.         $color = self::COLORS[$level] ?? self::COLORS[LogLevel::INFO];
  53.         $reset = self::COLORS['reset'];
  54.         $bold = self::COLORS['bold'];
  55.         $dim = self::COLORS['dim'];
  56.        
  57.         // Format the log line
  58.         echo sprintf(
  59.             "%s%s%s [%s%s%s] [%s%s%s]: %s%s%s\n",
  60.             $dim, $timestamp, $reset,
  61.             $color, strtoupper($level), $reset,
  62.             $bold, $channel->name, $reset,
  63.             $color, $message, $reset
  64.         );
  65.        
  66.         // Output context if not empty
  67.         if (!empty($context)) {
  68.             $contextOutput = $this->formatContext($context);
  69.             echo $contextOutput . "\n";
  70.         }
  71.        
  72.         // Add an empty line for better readability between log entries
  73.         echo "\n";
  74.     }
  75.    
  76.     /**
  77.      * Format context array for console output
  78.      */
  79.     private function formatContext(array $context, int $indent = 2): string
  80.     {
  81.         $output = '';
  82.         $indentStr = str_repeat(' ', $indent);
  83.        
  84.         foreach ($context as $key => $value) {
  85.             $output .= $indentStr . $key . ': ';
  86.            
  87.             if (is_array($value)) {
  88.                 $output .= "\n" . $this->formatContext($value, $indent + 2);
  89.             } elseif (is_object($value)) {
  90.                 if (method_exists($value, '__toString')) {
  91.                     $output .= (string)$value . "\n";
  92.                 } else {
  93.                     $output .= get_class($value) . "\n";
  94.                 }
  95.             } elseif (is_bool($value)) {
  96.                 $output .= ($value ? 'true' : 'false') . "\n";
  97.             } elseif (is_null($value)) {
  98.                 $output .= "null\n";
  99.             } else {
  100.                 $output .= $value . "\n";
  101.             }
  102.         }
  103.        
  104.         return $output;
  105.     }
  106.    
  107.     /**
  108.      * Format stack trace for better readability
  109.      */
  110.     private function formatTrace(string $trace): string
  111.     {
  112.         $lines = explode("\n", $trace);
  113.         // Just return first few lines to avoid overwhelming output
  114.         return implode("\n", array_slice($lines, 0, 5)) . (count($lines) > 5 ? "\n..." : "");
  115.     }
  116.    
  117.     /**
  118.      * Truncate response body if too long
  119.      */
  120.     private function truncateResponseBody(string $body, int $maxLength = 500): string
  121.     {
  122.         if (strlen($body) <= $maxLength) {
  123.             return $body;
  124.         }
  125.        
  126.         return substr($body, 0, $maxLength) . '... [truncated, total length: ' . strlen($body) . ' bytes]';
  127.     }
  128.    
  129.     // Shortcut methods for each log level
  130.     public function info(LogChannels $channel, $message, array $context = [], ?\Throwable $e = null, ?ResponseInterface $response = null): void
  131.     {
  132.         $this->log(LogLevel::INFO, $channel, $message, $context, $e, $response);
  133.     }
  134.  
  135.     public function debug(LogChannels $channel, $message, array $context = [], ?\Throwable $e = null, ?ResponseInterface $response = null): void
  136.     {
  137.         $this->log(LogLevel::DEBUG, $channel, $message, $context, $e, $response);
  138.     }
  139.  
  140.     public function error(LogChannels $channel, $message, array $context = [], ?\Throwable $e = null, ?ResponseInterface $response = null): void
  141.     {
  142.         $this->log(LogLevel::ERROR, $channel, $message, $context, $e, $response);
  143.     }
  144.  
  145.     public function warning(LogChannels $channel, $message, array $context = [], ?\Throwable $e = null, ?ResponseInterface $response = null): void
  146.     {
  147.         $this->log(LogLevel::WARNING, $channel, $message, $context, $e, $response);
  148.     }
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement