С недавним появлением PSR-3, стандарта для общего интерфейса для библиотек журналов, представляется целесообразным обсудить реализацию с моей любимой библиотекой журналов. log4php — это проект Apache с открытым исходным кодом, представляющий собой очень универсальную среду ведения журналов.
Через конфигурационные файлы log4php ведение журнала имеет множество выходных местоположений, поэтому можно отправлять определенные уровни журналов в разные выходные местоположения. Например: отладка, информация и уведомление используются главным образом для общего ведения журнала и отладки, и поэтому имеет смысл направить их в стандартный файл журнала, тогда как критическое значение и выше обычно означают, что что-то пошло не так с нашим приложением, и это делает больше смысл отправить их нам по электронной почте для немедленной диагностики.
Получение зависимостей
Прежде чем мы сможем начать писать код, нам нужно наши зависимости. Требуется класс интерфейса PSR-3; в настоящее время он находится на GitHub и может быть установлен через композитора из Packagist . Также требуется каркас log4php, который можно загрузить из Apache , с помощью PEAR или composer .
Вот пример файла composer.json
{
"require": {
"psr/log": "dev-master",
"apache/log4php": "2.3.0"
}
}
Упаковка log4php
Установив необходимые сторонние библиотеки, мы можем создать общий класс ведения журнала, который реализует интерфейс PSR-3 и использует log4php.
Интерфейс PSR-3 предоставляет восемь различных уровней журнала: отладка, информация, уведомление, предупреждение, ошибка, критическое состояние, предупреждение и аварийная ситуация. log4php содержит шесть уровней ведения журнала: трассировка, отладка, информация, предупреждение, ошибка и фатальный. Мы должны отобразить уровни PSR-3 на соответствующие уровни log4php. Приведенный ниже класс реализует интерфейс и управляет экземпляром log4php logger для сопоставления уровней.
<?php
require_once 'vendor/autoload.php';
class MyLogger implements PsrLogLoggerInterface
{
private $logger;
public function __construct($logger = 'main', $config = null) {
Logger::configure($config);
$this->logger = Logger::getLogger($logger);
}
/**
* System is unusable.
*
* @param string $message
* @param array $context
* @return null
*/
public function emergency($message, array $context = array()) {
$this->logger->fatal($this->interpolate($message, $context));
}
/**
* Action must be taken immediately.
*
* @param string $message
* @param array $context
* @return null
*/
public function alert($message, array $context = array()) {
$this->logger->fatal($this->interpolate($message, $context));
}
/**
* Critical conditions.
*
* @param string $message
* @param array $context
* @return null
*/
public function critical($message, array $context = array()) {
$this->logger->fatal($this->interpolate($message, $context));
}
/**
* Runtime errors that do not require immediate action but should
* be logged and monitored.
*
* @param string $message
* @param array $context
* @return null
*/
public function error($message, array $context = array()) {
$this->logger->error($this->interpolate($message, $context));
}
/**
* Exceptional occurrences that are not errors.
*
* @param string $message
* @param array $context
* @return null
*/
public function warning($message, array $context = array()) {
$this->logger->warn($this->interpolate($message, $context));
}
/**
* Normal but significant events.
*
* @param string $message
* @param array $context
* @return null
*/
public function notice($message, array $context = array()) {
$this->logger->info($this->interpolate($message, $context));
}
/**
* Interesting events.
*
* @param string $message
* @param array $context
* @return null
*/
public function info($message, array $context = array()) {
$this->logger->info($this->interpolate($message, $context));
}
/**
* Detailed debug information.
*
* @param string $message
* @param array $context
* @return null
*/
public function debug($message, array $context = array()) {
$this->logger->debug($this->interpolate($message, $context));
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param array $context
* @return null
*/
public function log($level, $message, array $context = array()) {
throw new Exception('Please call specific logging message');
}
/**
* Interpolates context values into the message placeholders.
* Taken from PSR-3's example implementation.
*/
protected function interpolate($message, array $context = array()) {
// build a replacement array with braces around the context
// keys
$replace = array();
foreach ($context as $key => $val) {
$replace['{' . $key . '}'] = $val;
}
// interpolate replacement values into the message and return
return strtr($message, $replace);
}
}
Помимо реализации интерфейса PSR-3, этот класс содержит конструктор, который принимает 2 необязательных параметра с именами $logger
$config
Первый параметр позволяет указать имя для регистратора, и log4php будет поддерживать ссылку на него, позволяя одновременно поддерживать несколько экземпляров регистратора с разными именами. Второй параметр позволяет указать файл конфигурации. Если ничего не указано, log4php будет использовать конфигурацию по умолчанию.
Недавно созданный класс MyLogger
<?php
$logger = new MyLogger();
$logger->debug('My debug test');
Параметр log4php по умолчанию для отладки выведет сообщение на стандартный вывод, поэтому результаты этого примера будут отправлены в веб-браузер.
Конфигурация log4php
log4php поставляется с конфигурацией по умолчанию, поэтому мы сразу приступим к ее использованию, но она также предоставляет возможность переопределить конфигурацию с использованием кода XML или PHP. Наиболее популярной поддерживаемой конфигурацией является XML.
Давайте создадим файл config.xml
<configuration xmlns="http://logging.apache.org/log4php/">
<appender name="myAppender" class="LoggerAppenderFile">
<param name="file" value="myLog.log"/>
</appender>
<root>
<level value="WARN"/>
<appender_ref ref="myAppender"/>
</root>
</configuration>
Теперь нам нужно передать имя нового файла конфигурации MyLogger
<?php
$logger = new MyLogger('main', 'config.xml');
$logger->debug('My debug test');
Если вы повторно запустите пример, когда вызывается сообщение отладки, log4php проигнорирует его, потому что отладка находится под предупреждением ниже, а наша конфигурация регистрирует только предупреждения и выше.
Вывод
Благодаря использованию интерфейса ведения журнала PSR-3 и log4php, совместимое со стандартами ведение журнала теперь чрезвычайно просто добавить в любой из наших проектов. Чтобы узнать больше о log4php, посетите краткое руководство . Подробнее о PSR-3 читайте в стандарте на GitHub .
Изображение через Fotolia