這多是php世界中最好的日誌庫——monolog

因爲一些歷史緣由,php中並無內建的日誌接口,故長期以來也沒一個功能完備而且應用普遍的日誌庫。在個人工做生涯中,若是系統須要記錄一些應用日誌的話,基本上就是封裝一個日誌類,而後把一些要記錄的字段寫入到磁盤文件。php

這樣就不免要一遍一遍的造輪子,而且在沒有一個規範的狀況下,記錄下來的日誌也是不方便分析的。可是但願讀完本文後但願大家能夠放棄本身造這種日誌類的輪子了,由於幾乎你不可能造得比咱們今天要介紹的主角:monolog更圓。json

monolog是一個爲5.3以上版本php開發的日誌庫,可是須要注意的是如今主幹版本只支持php 7以上版本,若是你的服務器環境仍是php 5的話,可使用monolog的1.x版本。設計模式

值得一提的是monolog是一個符合psr-3規範的日誌類庫,而且符合psr-4加載規範。若是有對psr規範不太瞭解的同窗能夠參看以下連接:http://www.php-fig.org/psr/,咱們在這裏就不具體介紹這些規範了,反正知道monolog是複合當前最新行業規範的日誌庫就夠了。服務器

若是想要在你的代碼中引入monolog的話只須要執行:數據結構

composer require monolog/monolog架構

mongolog中有幾個很重要的概念:app

第一個:handler 日誌管理器composer

存放handler的數據結構是一個「棧」,一個日誌實例能夠有多個handler,經過Logger實例的pushHandler方法壓入一個handler,該方法接受一個HandlerInterface類型的參數。若是你設置了多個handler,當你新增一條日誌的時候,他會從棧頂開始往下傳播,關心這個級別日誌的handler將會處理這條日誌。全部的handler都會繼承AbstractProcessingHandler這個抽象類,而且只須要實現裏面的抽象方法write就能夠了;同時這個抽象類會繼承AbstractHandler這個抽象類,這個抽象類的構造函數有兩個參數:level和bubble,前者表示該handler關心的最低日誌級別,是個整型,後者表示日誌被當前handler處理後是否接着向下傳遞。參照以下代碼:函數

use Monolog\Logger;學習

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

$logger = new Logger('my_logger');

$logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::INFO));

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::ERROR, false));

$logger->info('碼王教育——多是最具含金量的IT培訓');

如上這段代碼,這條日誌被ErrorLogHandler處理了,而且ErrorLogHandler的bubble參數設置爲false,則日誌不會被寫入my_app.log中了。

第二個:formatter 設置日誌格式

每一個handler能夠單獨設置記錄的日誌格式,AbstractHandler抽象類中有一個setFormatter方法,該參數接受一個FormatterInterface類型的參數。能夠看到monolog自帶的formatter都繼承自NormalizerFormatter,該類實現了format和formatBatch方法。咱們修改上面的示例代碼,讓兩個handler記錄不一樣格式的日誌:

use Monolog\Logger;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

use Monolog\Formatter\JsonFormatter;

$logger = new Logger('my_logger');

$stream_handler = new StreamHandler(__DIR__.'/my_app.log', Logger::INFO);

$stream_handler->setFormatter(new JsonFormatter());

$logger->pushHandler($stream_handler);

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::INFO));

$logger->info('碼王教育——多是最具含金量的IT培訓');

此時能夠看到my_app.log中記錄的日誌就變爲了更方便解析的json格式了。

第三個:processor 日誌處理器,用來給日誌添加額外信息

存放processor的結構也是一個「棧」,意味着你也能夠經過pushProcessor方法給一個Logger實例配置多個processor。咱們注意到,這裏pushProcessor接受一個callable,也就是須要一個函數或者類方法,可是官方自帶的這些processor都是類,隨便點進去一個源碼就會發現,其實這些類都用到了__invoke魔術方法,因此在被當作callable調用的時候會自動調用__invoke。咱們接着修改上面示例,給咱們的日誌加上更多信息:

use Monolog\Logger;

use Monolog\Handler\StreamHandler;

use Monolog\Handler\ErrorLogHandler;

use Monolog\Formatter\JsonFormatter;

use Monolog\Processor\UidProcessor;

use Monolog\Processor\ProcessIdProcessor;

$logger = new Logger('my_logger');

$stream_handler = new StreamHandler(__DIR__.'/my_app.log', Logger::INFO);

$stream_handler->setFormatter(new JsonFormatter());

$logger->pushHandler($stream_handler);

$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::OPERATING_SYSTEM, Logger::INFO));

$logger->pushProcessor(new UidProcessor);

$logger->pushProcessor(new ProcessIdProcessor);

$logger->info('碼王教育——多是最具含金量的IT培訓');

再次執行這段代碼就能看到,咱們在日的後面加上了uid和process_id。

經過以上的介紹相信你對monolog的使用和庫的總體架構都有一個比較系統的認識了,這個時候你應該能發現,本身開發一個handler、formatter、processor是如此簡單,只用實現兩個接口,再寫一個匿名函數,就能徹底控制本身的日誌處理方式和日誌格式了。

程序開發中很重要的一點就是像monolog這樣易於擴展,要作到這點其實只要遵照如下幾點:

一、依賴接口而不是實現(依賴反轉、設計模式)

二、在有標準的時候遵照行業標準(psr)

在學習完了monolog的用法和設計架構以後,何不如今在mongolog之上實現一套記錄日誌到關係型數據的代碼:)

更多的PHP進階學習資料盡在碼王信息,歡迎加羣632109190進行討論和學習

相關文章
相關標籤/搜索