Данный документ описывает общий интерфейс библиотек протоколирования.
Основная цель данного документа – позволить библиотекам получать объект PsrLogLoggerInterface и использовать его простым и универсальным образом для реализации протоколирования. В случае, если некий фреймворк или CMS нуждается в расширенном функционале, МОЖНО расширять данный интерфейс, но СЛЕДУЕТ сохранять совместимость с описанными в данном документе правилами. Это позволит сторонним библиотекам, применяемым при разработке приложения, использовать централизованную систему протоколирования.
Слово «разработчик» (implementor) в данном документе следует понимать как «автор, реализующий интерфейс LoggerInterface в неких библиотеке или фреймворке, связанных с протоколированием». Пользователи систем протоколирования упоминаются как просто «пользователи».
1. Спецификации
1.1 Основы
Интерфейс LoggerInterface предоставляет восемь методов протоколирования, соответствующих восьми уровням протоколирования, описанным в RFC 5424 (отладка (debug), информация (info), замечание (notice), предупреждение (warning), ошибка (error), критическая ошибка (critical), тревога (alert), авария (emergency)).
Девятый метод, «протокол» (log) принимает в качестве первого аргумента уровень протоколирования. Вызов этого метода с передачей константы одного из уровней протоколирования ДОЛЖЕН приводить к тому же результату, что и вызов соответствующего переданному уровню протоколирования специального метода.
Вызов этого метода с передачей уровня протоколирования, не описанного в данной спецификации, ДОЛЖЕН приводить к порождению исключения PsrLogInvalidArgumentException в случае, если конкретная реализация системы протоколирования не поддерживает переданный уровень протоколирования.
Пользователям НЕ СЛЕДУЕТ использовать собственные уровни протоколирования без полной уверенности в том, что конкретная реализация системы протоколирования их поддерживает.
1.2 Сообщения
-
Каждый метод протоколирования должен принимать строку-сообщение или объект с методом __toString(). Разработчики МОГУТ использовать специальные обработчики переданных объектов, но если этого не сделано, объект ДОЛЖЕН быть приведён к строке.
-
Строка-сообщение МОЖЕТ содержать плейсхолдеры, которые МОГУТ быть заменены на конкретные значения из массива context.
-
Имена плейсхолдеров ДОЛЖНЫ совпадать со значениями ключей массива context.
-
Плейсхолдеры ДОЛЖНЫ быть заключены в одиночные фигурные скобки, при этом НЕ ДОЛЖНО быть пробелов между фигурными скобками и именем плейсхолдера.
-
Имена плейсхолдеров НУЖНО составлять только из символов A-Z, a-z, 0-9/span<, знак подчёркивания (_) и точка (.). Остальные символы зарезервированы для будущих изменений в спецификации плейсхолдеров.
-
Разработчики МОГУТ реализовывать со значениями плейсхолдеров различные стратегии экранирования и преобразования при отображении протокола. Пользователям НЕ НУЖНО предварительно экранировать данные в значениях плейсхолдеров, т.к. заранее не известно, как и в каком контексте содержащаяся в них информация может быть использована.
Ниже для ознакомления представлен пример обработки плейсхолдеров.
<?php /** * Подстановка значений в плейсхолдеры сообщения. */ function interpolate($message, array $context = array()) { // Построение массива подстановки с фигурными скобками // вокруг значений ключей массива context. $replace = array(); foreach ($context as $key => $val) { $replace['{' . $key . '}'] = $val; } // Подстановка значений в сообщение и возврат результата. return strtr($message, $replace); } // Сообщение с плейсхолдером, имя которого обрамлено // фигурными скобками. $message = "User {username} created"; // Массив context с данными для замены плейсхолдера на // итоговое значение. $context = array('username' => 'bolivar'); // Результат: "User bolivar created" echo interpolate($message, $context);
1.3 Контекст
Каждый метод получает массив сопутствующих данных (context), содержащих дополнительную информацию, представление которой в виде строки не является оптимальным. На содержимое массива не налагается никаких ограничений. Разработчики ДОЛЖНЫ обрабатывать данные массива context максимально гибко. Переданные в массиве context данные НЕ ДОЛЖНЫ порождать исключений, вызывать сообщений об ошибках, предупреждений или замечаний от интерпретатора PHP.
Если в массив context передан объект исключения, он ДОЛЖЕН находиться в элементе с ключом exception. Протоколирование исключений является распространённой практикой и позволяет разработчикам извлекать данные трассировки стека, если система протоколирования поддерживает такую функциональность. Разработчики ДОЛЖНЫ удостовериться, что в элементе с ключом exception на самом деле находится объект исключения, т.к. в реальности там МОЖЕТ оказаться что угодно.
1.4 Вспомогательные классы и интерфейсы
-
Класс PsrLogAbstractLogger позволяет очень легко реализовать интерфейс LoggerInterface – достаточно создать свой класс-наследник и реализовать там метод log. Остальные восемь методов будут передавать сообщения и контекст в этот метод.
-
Аналогично, использование PsrLogLoggerTrait требует всего лишь реализовать метод log. Однако в связи с тем, что примеси не могут реализовывать интерфейсы, вам всё равно придётся реализовать LoggerInterface.
-
Класс PsrLogNullLogger, поставляемый с соответствующим интерфейсом, МОЖЕТ быть использован для реализации «записи протокола в пустоту», однако условное протоколирование может оказаться лучшим решением в случае, если создание контекстной информации является затратной операцией.
-
Интерфейс PsrLogLoggerAwareInterface содержит только метод setLogger(LoggerInterface $logger) и может быть использован для автоматического связывания необходимых сущностей с системой протоколирования.
-
Примесь PsrLogLoggerAwareTrait может быть легко использована для реализации соответствующего интерфейса. Она предоставляет доступ к $this->logger.
-
Класс PsrLogLogLevel содержит константы восьми уровней протоколирования.
2. Пакет
Описанные интерфейсы и классы, равно как и соответствующие классы исключений и тестовые сценарии для проверки вашей реализации системы протоколирования предоставляются в составе пакета psr/log.
3. Интерфейс PsrLogLoggerInterface
<?php namespace PsrLog; /** * Описывает систему протоколирования. * * Сообщение ДОЛЖНО быть строкой или объектом, реализующим __toString(). * * Сообщение МОЖЕТ содержать плейсхолдеры в виде {foo}, где foo будет * заменено на значение элемента массива context с ключом "foo". * * Массив context может содержать произвольные данные. Единственное * предположение, допустимое для разработчиков, заключается в том, что * если в массиве переда объект исключения для построения трассировки * стека, он ДОЛЖЕН находиться в элементе массива с ключом "exception". * * См. полную спецификацию интерфейса здесь: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md */ interface LoggerInterface { /** * Авария, система неработоспособна. * * @param строка $message * @param массив $context * @return null */ public function emergency($message, array $context = array()); /** * Тревога, меры должны быть предприняты незамедлительно. * * Примеры: весь веб-сайт недоступен, БД недоступна и т.д. Вплоть до * отправки SMS-сообщения ответственному лицу. * * @param строка $message * @param массив $context * @return null */ public function alert($message, array $context = array()); /** * Критическая ошибка, критическая ситуация. * * Пример: недоступен компонент приложения, неожиданное исключение. * * @param строка $message * @param массив $context * @return null */ public function critical($message, array $context = array()); /** * Ошибка на стадии выполнения, не требующая неотложного вмешательства, * но требующая протоколирования и дальнейшего изучения. * * @param строка $message * @param массив $context * @return null */ public function error($message, array $context = array()); /** * Предупреждение, нештатная ситуация, не являющаяся ошибкой. * * Пример: использование устаревшего API, неверное использование API, * нежелательные эффекты и ситуации, которые, тем не менее, * не обязательно являются ошибочными. * * @param строка $message * @param массив $context * @return null */ public function warning($message, array $context = array()); /** * Замечание, важное событие. * * @param строка $message * @param массив $context * @return null */ public function notice($message, array $context = array()); /** * Информация, полезные для понимания происходящего события. * * Пример: авторизация пользователя, протокол взаимодействия с БД. * * @param строка $message * @param массив $context * @return null */ public function info($message, array $context = array()); /** * Детальная отладочная информация. * * @param строка $message * @param массив $context * @return null */ public function debug($message, array $context = array()); /** * Протоколирование с произвольным уровнем. * * @param смешанный $level * @param строка $message * @param массив $context * @return null */ public function log($level, $message, array $context = array());
4. Интерфейс PsrLogLoggerAwareInterface
<?php namespace PsrLog; /** * Описывает систему, поддерживающую протоколирование. */ interface LoggerAwareInterface { /** * Устанавливает объект протоколирования в объект * системы, поддерживающей протоколирование. * * @param LoggerInterface $logger * @return null */ public function setLogger(LoggerInterface $logger); }
5. Класс PsrLogLogLevel
<?php namespace PsrLog; /** * Описывает уровни протоколирования. */ class LogLevel { const EMERGENCY = 'emergency'; const ALERT = 'alert'; const CRITICAL = 'critical'; const ERROR = 'error'; const WARNING = 'warning'; const NOTICE = 'notice'; const INFO = 'info'; const DEBUG = 'debug'; }
Нет Ответов