attach($writer); * * @param Log_Writer $writer instance * @param mixed $levels array of messages levels to write OR max level to write * @param integer $min_level min level to write IF $levels is not an array * @return Log */ public function attach(Log_Writer $writer, $levels = [], $min_level = 0) { if ( ! is_array($levels)) { $levels = range($min_level, $levels); } $this->_writers["{$writer}"] = [ 'object' => $writer, 'levels' => $levels ]; return $this; } /** * Detaches a log writer. The same writer object must be used. * * $log->detach($writer); * * @param Log_Writer $writer instance * @return Log */ public function detach(Log_Writer $writer) { // Remove the writer unset($this->_writers["{$writer}"]); return $this; } /** * Adds a message to the log. Replacement values must be passed in to be * replaced using [strtr](http://php.net/strtr). * * $log->add(Log::ERROR, 'Could not locate user: :user', array( * ':user' => $username, * )); * * @param string $level level of message * @param string $message message body * @param array $values values to replace in the message * @param array $additional additional custom parameters to supply to the log writer * @return Log */ public function add($level, $message, array $values = NULL, array $additional = NULL) { if ($values) { // Insert the values into the message $message = strtr($message, $values); } // Grab a copy of the trace if (isset($additional['exception'])) { $trace = $additional['exception']->getTrace(); } else { // Older php version don't have 'DEBUG_BACKTRACE_IGNORE_ARGS', so manually remove the args from the backtrace if ( ! defined('DEBUG_BACKTRACE_IGNORE_ARGS')) { $trace = array_map(function ($item) { unset($item['args']); return $item; }, array_slice(debug_backtrace(FALSE), 1)); } else { $trace = array_slice(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), 1); } } if ($additional == NULL) { $additional = []; } // Create a new message $this->_messages[] = [ 'time' => time(), 'level' => $level, 'body' => $message, 'trace' => $trace, 'file' => isset($trace[0]['file']) ? $trace[0]['file'] : NULL, 'line' => isset($trace[0]['line']) ? $trace[0]['line'] : NULL, 'class' => isset($trace[0]['class']) ? $trace[0]['class'] : NULL, 'function' => isset($trace[0]['function']) ? $trace[0]['function'] : NULL, 'additional' => $additional, ]; if (Log::$write_on_add) { // Write logs as they are added $this->write(); } return $this; } /** * Write and clear all of the messages. * * $log->write(); * * @return void */ public function write() { if (empty($this->_messages)) { // There is nothing to write, move along return; } // Import all messages locally $messages = $this->_messages; // Reset the messages array $this->_messages = []; foreach ($this->_writers as $writer) { if (empty($writer['levels'])) { // Write all of the messages $writer['object']->write($messages); } else { // Filtered messages $filtered = []; foreach ($messages as $message) { if (in_array($message['level'], $writer['levels'])) { // Writer accepts this kind of message $filtered[] = $message; } } // Write the filtered messages $writer['object']->write($filtered); } } } }