PHP Fig - PSR-3 日志接口(Logger Interface)

·694 字·4 分钟
PHP php FIG PSR
n3xtchen
作者
n3xtchen
Sharing Funny Tech With You

译自 http://www.php-fig.org/psr/psr-3/

这个文档用来描述日志操作库的通用接口;

主要目的是为了允许代码库接受 Psr\Log\LoggerInterface 对象,以简单通用的方式 记录日志;框架和 CMSs 可通过该接口定制他们需要的日志系统,但是必须兼容这个文档; 这个是为了确保程序使用的地方库可以写到集中的应用日志系统中。

文档中的 implementor 被解释成他人通过 LoggerInterface 接口的实现;日志的用户 就是 user;

1. 说明(Sepecification) #

1.1 基础(Basic) #

  • LoggerInterface 抛出8个方法用来记录 8 种 RFC 5424 等级的版本(debug,info, notice,warning,error,critical,alert,emergency);

  • 第九个方法 log 接受日志登记作为第一个参数;用一个日志等级常量来调用这个方法的 结果必须和调用具体等级方法的一致。如果具体的实现不知道传入的不按规范的等级来 调用这个方法必须抛出一个 Psr\Log\InvalidArgumentException;用户不应自定义一个 当前不支持的未知等级。

1.2 信息(Message) #

  • 每个方法应该接受一个字符串作为信息,或者是带有 __toString() 的对象; 实现(Implementors)可以对传入对象进行特殊处理。如果不是那种情况;实现 (Implementors) 必须将它 转化成字符串;

  • 信息可以包含占位符;这样可以根据上下文数据对其进行替换;

占位符名称应该和对应的数据的键相匹配;

占位符必须使用花括号({})来界定(即包围);界定符和名称之间不可以有空格;

占位符名应该只包含大小写字母,下划线(_)以及点号(.);其他字符的使用由将来的 规格变更需要时添加;

实现(Implementors)可以使用占位符实现各种转义;用户不了解上下文的情况不应该 体现转移占位符的值;

下面是占位符转义的实现(Implementors)例子:

/**
  * Interpolates context values into the message placeholders.
  */
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);
}

// a message with brace-delimited placeholder names
$message = "User {username} created";

// a context array of placeholder names => replacement values
$context = array('username' => 'bolivar');

// echoes "User bolivar created"
echo interpolate($message, $context);

1.3 上下文(Context) #

  • 方法接受一个关联上文数据的数组参数;这意味着这意味着可能包含大量与数组无关 的数据;数组可以包含任何东西;实现(Implementors)必须对关联上下文数据竟可能 仁慈;传入的值不得抛出任何异常,错误,警告或者提示;

  • 如果 Exception 作为上下文传入;它必须存储在 exception 的键中;日志异常是 一个通用的模式,它允许实现(Implementors)提取其中的信息;实现(Implementors) 可以识别 excpetion 的键来处理异常对象;正因为他可以包含任何东西;

1.4 帮助类和接口 #

  • 托张 Psr\Log\AbstractLogger 类让你很容易实现 LoggerInterface 的通用 log 方法;其他八个方法通过它来转发信息;

  • 类似的,使用 Psr\Log\LoggerTrait 只需要你实现通用的log方法。记住traits不能 实现接口前,你依然需要 implement LoggerInterface;

  • Psr\Log\NullLogger 是和接口一起提供的。它可以为使用接口的用户提供一个后备的 “黑洞”。如果上下文数据非常重要,这不失为一个记录日志更好的办法。

  • Psr\Log\LoggerAwareInterface 只有一个setLogger(LoggerInterface $logger)方法 可以用来随意设置一个日志记录器。

  • Psr\Log\LoggerAwareTraittrait 可以更简单的实现等价于接口。通过它可以访问 到$this->logger。

  • Psr\Log\LogLevel 类拥有八个等级的常量。

2. 包(Package) #

PSR/log 包中包含之前描述的接口和类,还有相关的异常类以及验证你实现的测试包;

3. Psr\Log\LoggerInterface #

<?php

namespace Psr\Log;

/**
 * Describes a logger instance
 *
 * The message MUST be a string or object implementing __toString().
 *
 * The message MAY contain placeholders in the form: {foo} where foo
 * will be replaced by the context data in key "foo".
 *
 * The context array can contain arbitrary data, the only assumption that
 * can be made by implementors is that if an Exception instance is given
 * to produce a stack trace, it MUST be in a key named "exception".
 *
 * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
 * for the full interface specification.
 */
interface LoggerInterface
{
    /**
     * System is unusable.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function emergency($message, array $context = array());

    /**
     * Action must be taken immediately.
     *
     * Example: Entire website down, database unavailable, etc. This should
     * trigger the SMS alerts and wake you up.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function alert($message, array $context = array());

    /**
     * Critical conditions.
     *
     * Example: Application component unavailable, unexpected exception.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function critical($message, array $context = array());

    /**
     * Runtime errors that do not require immediate action but should typically
     * be logged and monitored.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function error($message, array $context = array());

    /**
     * Exceptional occurrences that are not errors.
     *
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
     * that are not necessarily wrong.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function warning($message, array $context = array());

    /**
     * Normal but significant events.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function notice($message, array $context = array());

    /**
     * Interesting events.
     *
     * Example: User logs in, SQL logs.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function info($message, array $context = array());

    /**
     * Detailed debug information.
     *
     * @param string $message
     * @param array $context
     * @return null
     */
    public function debug($message, array $context = array());

    /**
     * Logs with an arbitrary level.
     *
     * @param mixed $level
     * @param string $message
     * @param array $context
     * @return null
     */
    public function log($level, $message, array $context = array());
}

4. Psr\Log\LoggerAwareInterface #

<?php

namespace Psr\Log;

/**
 * Describes a logger-aware instance
 */
interface LoggerAwareInterface
{
    /**
     * Sets a logger instance on the object
     *
     * @param LoggerInterface $logger
     * @return null
     */
    public function setLogger(LoggerInterface $logger);
}

5. Psr\Log\LogLevel #

<?php

namespace Psr\Log;

/**
 * Describes log levels
 */
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';
}