上節聊完了PHP官方的相關代碼規範,下麵給大家帶來了PHP系列的PHP推薦標準的另外兩個,PSR-3,PSR-4。 首先,我們先來瞭解下PSR-3是怎麼回事。 PHP-FIG發佈的第三個推薦規範與前兩個不同,不是一系列的指導方針,而是一個介面,規定PHP日誌記錄器組件可以實現的方法。 基礎 The ...
上節聊完了PHP官方的相關代碼規範,下麵給大家帶來了PHP系列的PHP推薦標準的另外兩個,PSR-3,PSR-4。
首先,我們先來瞭解下PSR-3是怎麼回事。
PHP-FIG發佈的第三個推薦規範與前兩個不同,不是一系列的指導方針,而是一個介面,規定PHP日誌記錄器組件可以實現的方法。
基礎
The LoggerInterface
exposes eight methods to write logs to the eight RFC 5424levels (debug, info, notice, warning, error, critical, alert, emergency).
<?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()); }
A ninth method, log
, accepts a log level as the first argument. Calling this method with one of the log level constants MUST have the same result as calling the level-specific method.
Message參數
1、Every method accepts a string as the message, or an object with a__toString()
method. Implementors MAY have special handling for the passed objects. If that is not the case, implementors MUST cast it to a string.
2、The message MAY contain placeholders which implementors MAY replace with values from the context array.
Placeholder names MUST correspond to keys in the context array.
Implementors MAY use placeholders to implement various escaping strategies and translate logs for display. Users SHOULD NOT pre-escape placeholder values since they can not know in which context the data will be displayed.
總的來講,占位符是為後面的Context參數提供占位服務,$context參數用於構造複雜的日誌消息,$context參數的值是一個關聯數組,鍵是占位符的名稱(不能有花括弧),對應的值用於替換Message參數中的占位符。
The following is an example implementation of placeholder interpolation provided for reference purposes only:
/** * 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) { // check that the value can be casted to string if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) { $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);
Context參數
1、Every method accepts an array as context data. This is meant to hold any extraneous information that does not fit well in a string.
2、If an Exception
object is passed in the context data, it MUST be in the'exception'
key.
這個參數是可選的,提供用於替換message參數中的占位標記的值。
輔助類和介面
1、The Psr\Log\AbstractLogger
class lets you implement the LoggerInterface
very easily by extending it and implementing the generic log
method. The other eight methods are forwarding the message and context to it.
2、Similarly, using the Psr\Log\LoggerTrait
only requires you to implement the generic log
method. Note that since traits can not implement interfaces, in this case you still have to implement LoggerInterface
.
3、The Psr\Log\NullLogger
is provided together with the interface. It MAY be used by users of the interface to provide a fall-back “black hole” implementation if no logger is given to them. However, conditional logging may be a better approach if context data creation is expensive.
4、The Psr\Log\LoggerAwareInterface
only contains a setLogger(LoggerInterface $logger)
method and can be used by frameworks to auto-wire arbitrary instances with a logger.
<?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、The Psr\Log\LoggerAwareTrait
trait can be used to implement the equivalent interface easily in any class. It gives you access to $this->logger.
6、The Psr\Log\LogLevel
class holds constants for the eight log levels.
<?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'; }
總結
如果你想自己寫個PSR-3日誌記錄器,那可沒什麼必要了,因為已經有很多人乾過這件事了。
如果你正在使用Yii2.0框架寫代碼,你可以搜索下Logger.php這個文件,已經實現的非常好了。你需要做的只是一句簡單的:
Yii::info($message, $category);
即可,後面我會帶大家討論更多框架的事。
如果你不適用框架,楓爺這裡給大家推薦一個很好的組件:monolog/monolog。
Monolog已經完全實現了PSR-3的介面,而且便於使用自定義的消息格式化程式和處理程式擴展功能。
如果大家對monolog感興趣,可以去到他的官網進行查看,http://monolog.ow2.org/doc/index.html。
有了日誌收集功能,如何進行日誌的篩選,日誌的盤查啥的,楓爺再推薦大家一款非常好用的軟體,splunk,免費500M,超過部分要收錢,當然了,國人不會放過任何領域的,如果要免費,那就用用日誌易吧,我就用的他,感覺不錯的。
splunk:http://10data.com/splunk/
日誌易:https://www.rizhiyi.com/
至於怎麼用,大家可以先行去他們的官網先行瞭解,以後有機會,楓爺再教大家搭建日誌平臺的相關知識。