126 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php namespace Clockwork\Request;
 | |
| 
 | |
| use Clockwork\Helpers\Serializer;
 | |
| use Clockwork\Helpers\StackTrace;
 | |
| use Clockwork\Helpers\StackFilter;
 | |
| 
 | |
| // Data structure representing a log with timestamped messages
 | |
| class Log
 | |
| {
 | |
| 	// Array of logged messages
 | |
| 	public $messages = [];
 | |
| 
 | |
| 	// Create a new log, optionally with existing messages
 | |
| 	public function __construct($messages = [])
 | |
| 	{
 | |
| 		$this->messages = $messages;
 | |
| 	}
 | |
| 
 | |
| 	// Log a new message, with a level and context, context can be used to override serializer defaults,
 | |
| 	// $context['trace'] = true can be used to force collecting a stack trace
 | |
| 	public function log($level = LogLevel::INFO, $message = null, array $context = [])
 | |
| 	{
 | |
| 		$trace = $this->hasTrace($context) ? $context['trace'] : StackTrace::get()->resolveViewName();
 | |
| 
 | |
| 		$this->messages[] = [
 | |
| 			'message'   => (new Serializer($context))->normalize($message),
 | |
| 			'exception' => $this->formatException($context),
 | |
| 			'context'   => $this->formatContext($context),
 | |
| 			'level'     => $level,
 | |
| 			'time'      => microtime(true),
 | |
| 			'trace'     => (new Serializer(! empty($context['trace']) ? [ 'traces' => true ] : []))->trace($trace)
 | |
| 		];
 | |
| 	}
 | |
| 
 | |
| 	public function emergency($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::EMERGENCY, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function alert($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::ALERT, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function critical($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::CRITICAL, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function error($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::ERROR, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function warning($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::WARNING, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function notice($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::NOTICE, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function info($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::INFO, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	public function debug($message, array $context = [])
 | |
| 	{
 | |
| 		$this->log(LogLevel::DEBUG, $message, $context);
 | |
| 	}
 | |
| 
 | |
| 	// Merge another log instance into the current log
 | |
| 	public function merge(Log $log)
 | |
| 	{
 | |
| 		$this->messages = array_merge($this->messages, $log->messages);
 | |
| 
 | |
| 		return $this;
 | |
| 	}
 | |
| 
 | |
| 	// Sort the log messages by timestamp
 | |
| 	public function sort()
 | |
| 	{
 | |
| 		usort($this->messages, function ($a, $b) { return $a['time'] * 1000 - $b['time'] * 1000; });
 | |
| 	}
 | |
| 
 | |
| 	// Get all messages as an array
 | |
| 	public function toArray()
 | |
| 	{
 | |
| 		return $this->messages;
 | |
| 	}
 | |
| 
 | |
| 	// Format message context, removes exception and trace if we are serializing them
 | |
| 	protected function formatContext($context)
 | |
| 	{
 | |
| 		if ($this->hasException($context)) unset($context['exception']);
 | |
| 		if ($this->hasTrace($context)) unset($context['trace']);
 | |
| 
 | |
| 		return (new Serializer)->normalize($context);
 | |
| 	}
 | |
| 
 | |
| 	// Format exception if present in the context
 | |
| 	protected function formatException($context)
 | |
| 	{
 | |
| 		if ($this->hasException($context)) {
 | |
| 			return (new Serializer)->exception($context['exception']);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Check if context has serializable trace
 | |
| 	protected function hasTrace($context)
 | |
| 	{
 | |
| 		return ! empty($context['trace']) && $context['trace'] instanceof StackTrace && empty($context['raw']);
 | |
| 	}
 | |
| 
 | |
| 	// Check if context has serializable exception
 | |
| 	protected function hasException($context)
 | |
| 	{
 | |
| 		return ! empty($context['exception'])
 | |
| 			&& ($context['exception'] instanceof \Throwable || $context['exception'] instanceof \Exception)
 | |
| 			&& empty($context['raw']);
 | |
| 	}
 | |
| }
 | 
