日志
日志可以快速幫助開(kāi)發(fā)者快速定位問(wèn)題的根源、追蹤程序執(zhí)行的過(guò)程、追蹤數(shù)據(jù)變化、數(shù)據(jù)統(tǒng)計(jì)和性能分析等。
配置說(shuō)明
EasySwoole 在 3.4.4 版本中優(yōu)化了框架默認(rèn)的日志處理機(jī)制,允許用戶(hù)更加方便地去自定義配置日志處理,可以直接在配置文件 (dev.php/produce.php) 中進(jìn)行配置。(以后版本也將兼容以下配置特性)
配置包括以下幾方面:
- 設(shè)置記錄日志文件時(shí)日志文件存放目錄 (dir),用戶(hù)可以自己設(shè)置日志存放目錄(但是一定要保證日志有寫(xiě)入權(quán)限),配置值為
路徑,默認(rèn)為框架根目錄的 Log 目錄。 - 設(shè)置記錄日志時(shí)的日志最低等級(jí) (level),等級(jí)配置值默認(rèn)為
\EasySwoole\Log\LoggerInterface::LOG_LEVEL_DEBUG,等級(jí)值支持\EasySwoole\Log\LoggerInterface::LOG_LEVEL_DEBUG (0級(jí))、\EasySwoole\Log\LoggerInterface::LOG_LEVEL_INFO (1級(jí))、\EasySwoole\Log\LoggerInterface::LOG_LEVEL_NOTICE (2級(jí))、\EasySwoole\Log\LoggerInterface::LOG_LEVEL_WARNING (3級(jí))、\EasySwoole\Log\LoggerInterface::LOG_LEVEL_ERROR (4級(jí))。例如當(dāng)我們?cè)谂渲梦募邪讶罩镜燃?jí)設(shè)置為\EasySwoole\Log\LoggerInterface::LOG_LEVEL_INFO (1級(jí))時(shí),就不會(huì)把我們?cè)诳蚣苤姓{(diào)用打印小于這個(gè)等級(jí)的日志記錄記錄到日志文件中 (比如LOG_LEVEL_DEBUG (0級(jí))就不會(huì)被記錄到日志當(dāng)中了,也不會(huì)顯示在控制臺(tái)了)。 - 設(shè)置日志處理器
handler(handler),默認(rèn)使用框架內(nèi)置handler,用戶(hù)可以自定義日志類(lèi)實(shí)現(xiàn)\EasySwoole\Log\LoggerInterface接口,來(lái)處理記錄日志。配置值為自定義處理類(lèi)名,默認(rèn)為\EasySwoole\Log\Logger。具體自定義實(shí)現(xiàn)日志處理器可看下文。 - 設(shè)置記錄日志到日志文件時(shí)是否在控制臺(tái)打印日志 (logConsole)。配置值為
boolean值,默認(rèn)為true,即開(kāi)啟。 - 設(shè)置是否開(kāi)啟在控制臺(tái)打印日志 (displayConsole)。配置值為
boolean值,默認(rèn)為true,即開(kāi)啟。 - 設(shè)置打印日志時(shí)忽略哪些分類(lèi)的日志不進(jìn)行記錄 (ignoreCategory) 。配置值為
array類(lèi)型值,默認(rèn)為null(即不忽略任何分類(lèi)的日志,任何分類(lèi)的日志都進(jìn)行在控制臺(tái)顯示打印并記錄到文件),配置忽略分類(lèi)值支持debug、info、notice、warning、error作為配置值array中的可選值。例如:設(shè)置為['debug', 'notice']時(shí),即當(dāng)我們?cè)诳蚣苤惺褂孟旅媪信e的使用日志的方法時(shí),調(diào)用debug和notice方法記錄日志時(shí),不會(huì)把debug和notice分類(lèi)的日志在控制臺(tái)顯示,也不會(huì)記錄到日志文件中。
下面為配置文件中配置示例:
<?php
use EasySwoole\Log\LoggerInterface;
return [
// ... 這里省略
'MAIN_SERVER' => [
// ... 這里省略
],
"LOG" => [
// 設(shè)置記錄日志文件時(shí)日志文件存放目錄
'dir' => null,
// 設(shè)置記錄日志時(shí)的日志最低等級(jí),低于此等級(jí)的日志不進(jìn)行記錄和顯示
'level' => LoggerInterface::LOG_LEVEL_DEBUG,
// 設(shè)置日志處理器 `handler` (handler)
'handler' => null,
// 設(shè)置開(kāi)啟在記錄日志到日志文件時(shí)在控制臺(tái)打印日志
'logConsole' => true,
// 設(shè)置開(kāi)啟在控制臺(tái)顯示日志
'displayConsole'=>true,
// 設(shè)置打印日志時(shí)忽略哪些分類(lèi)的日志不進(jìn)行記錄
'ignoreCategory' => []
],
// ... 這里省略
];
以上 level 和 ignoreCategory 的設(shè)置,更加方便用戶(hù)在正式上線(xiàn)項(xiàng)目時(shí),屏蔽那些在開(kāi)發(fā)階段的調(diào)試日志不進(jìn)行記錄和顯示。當(dāng)然對(duì)于 PHP 異常錯(cuò)誤等級(jí) 的等級(jí)設(shè)置(即 error_reporting()),用戶(hù)也可以設(shè)置,詳細(xì)請(qǐng)查看 iniialize 事件中設(shè)置ERROR_LEVEL。
注意:在
EasySwoole 3.4.3 版本中,僅支持對(duì)上述dir、level、handler的配置。而在3.4.2之前版本中,僅支持對(duì)上述dir的配置。
日志使用
以下方法可以在框架的 boostrap 事件之后的任意位置進(jìn)行調(diào)用。調(diào)用之前請(qǐng)先看下文注意事項(xiàng)。
在非框架中使用,例如是單元測(cè)試腳本,請(qǐng)執(zhí)行 \EasySwoole\EasySwoole\Core::getInstance()->initialize(); 用于初始化日志。
在 EasySwoole 3.3.7 之前版本中,initialize 事件調(diào)用為:EasySwoole\EasySwoole\Core::getInstance()->initialize()->globalInitialize();。
log 記錄顯示日志
// 打印和記錄 `DEBUG` 等級(jí)、`debug` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->log('record level:DEBUG-category:debug log info',\EasySwoole\Log\LoggerInterface::LOG_LEVEL_DEBUG,'debug');
### [舊版本說(shuō)明] 注意:當(dāng)找不到 `\EasySwoole\Log\LoggerInterface::LOG_LEVEL_DEBUG` 常量,請(qǐng)查看是否為 `\EasySwoole\EasySwoole\Logger::LOG_LEVEL_INFO`
// 打印和記錄 `INFO` 等級(jí)、`info` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->log('record level:INFO-category:info log info',\EasySwoole\Log\LoggerInterface::LOG_LEVEL_INFO,'info');
// 打印和記錄 `NOTICE` 等級(jí)、`notice` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->log('record level:NOTICE-category:notice log info',\EasySwoole\Log\LoggerInterface::LOG_LEVEL_NOTICE,'notice');
// 打印和記錄 `WARNING` 等級(jí)、`warning` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->log('record level:WARNING-category:warning log info',\EasySwoole\Log\LoggerInterface::LOG_LEVEL_WARNING,'warning');
// 打印和記錄 `ERROR` 等級(jí)、`error` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->log('record level:ERROR-category:error log info',\EasySwoole\Log\LoggerInterface::LOG_LEVEL_ERROR,'error');
運(yùn)行結(jié)果:在控制臺(tái)和日志文件 Log\log_XxxxXx.log 中均可看到如下結(jié)果:
// 格式說(shuō)明: [記錄日志時(shí)間][分類(lèi)][等級(jí)]:[日志內(nèi)容]
[2021-03-18 22:52:09][debug][debug]:[record level:DEBUG-category:debug log info]
[2021-03-18 22:52:09][info][info]:[record level:INFO-category:info log info]
[2021-03-18 22:52:09][notice][notice]:[record level:NOTICE-category:notice log info]
[2021-03-18 22:52:09][warning][warning]:[record level:WARNING-category:warning log info]
[2021-03-18 22:52:09][error][error]:[record level:ERROR-category:error log info]
info 日志
// 打印和記錄 `INFO` 等級(jí)、`info` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->info('record level:INFO-category:info log info');
waring 日志
// 打印和記錄 `WANING` 等級(jí)、`waring` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->waring('record level:WANING-category:waring log info');
console 日志
// 只在控制臺(tái)打印 `INFO` 等級(jí)、`debug` 分類(lèi)的日志 (不記錄日志文件)
\EasySwoole\EasySwoole\Logger::getInstance()->console('console', \EasySwoole\Log\LoggerInterface::LOG_LEVEL_INFO, 'debug');
notice 日志
// 打印和記錄 `NOTICE` 等級(jí)、`notice` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->notice('record level:NOTICE-category:notice log info');
error 日志
// 打印和記錄 `ERROR` 等級(jí)、`error` 分類(lèi)的日志
\EasySwoole\EasySwoole\Logger::getInstance()->error('record level:ERROR-category:error log info');
event 日志寫(xiě)入后執(zhí)行回調(diào)
使用 event 時(shí),請(qǐng)先注冊(cè) Event。
// 日志寫(xiě)入之后執(zhí)行
\EasySwoole\EasySwoole\Logger::getInstance()->onLog()->set('myHook', function ($msg, $logLevel, $category) {
// 增加日志寫(xiě)入之后的回調(diào)函數(shù)
});
自定義日志處理器
需要實(shí)現(xiàn) EasySwoole\Log\LoggerInterface 即可:
自定義示例如下,新建 App\Log\LogHandler.php 文件,編輯內(nèi)容如下:
<?php
namespace App\Log;
use EasySwoole\Log\LoggerInterface;
class LogHandler implements LoggerInterface
{
private $logDir;
function __construct(string $logDir = null)
{
if (empty($logDir)) {
$logDir = getcwd();
}
$this->logDir = $logDir;
}
function log(?string $msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'debug'): string
{
$date = date('Y-m-d H:i:s');
$levelStr = $this->levelMap($logLevel);
$filePath = $this->logDir . "/log_{$category}.log";
$str = "自定義日志:[{$date}][{$category}][{$levelStr}] : [{$msg}]\n";
file_put_contents($filePath, "{$str}", FILE_APPEND | LOCK_EX);
return $str;
}
function console(?string $msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'console')
{
$date = date('Y-m-d H:i:s');
$levelStr = $this->levelMap($logLevel);
$temp = "自定義日志:[{$date}][{$category}][{$levelStr}]:[{$msg}]\n";
fwrite(STDOUT, $temp);
}
private function levelMap(int $level)
{
switch ($level) {
case self::LOG_LEVEL_INFO:
return 'info';
case self::LOG_LEVEL_NOTICE:
return 'notice';
case self::LOG_LEVEL_WARNING:
return 'warning';
case self::LOG_LEVEL_ERROR:
return 'error';
default:
return 'unknown';
}
}
}
注冊(cè)自定義日志處理器
(
EasySwoole 3.4.4及以上版本可使用) 方法1. 在配置文件 (dev.php/produce.php)中注冊(cè)自定義日志處理器
<?php
use EasySwoole\Log\LoggerInterface;
return [
// ... 這里省略
'MAIN_SERVER' => [
// ... 這里省略
],
"LOG" => [
'dir' => null,
'level' => LoggerInterface::LOG_LEVEL_DEBUG,
// 注冊(cè)日志處理器 `handler` (handler)
'handler' => new \App\Log\LogHandler(),
'logConsole' => true,
'displayConsole'=>true,
'ignoreCategory' => []
],
// ... 這里省略
];
(
EasySwoole 3.4.x+版本可使用) 方法2. 在initialize事件 中注冊(cè)自定義logger處理器
注冊(cè)示例代碼如下:
<?php
namespace EasySwoole\EasySwoole;
use EasySwoole\EasySwoole\AbstractInterface\Event;
use EasySwoole\EasySwoole\Swoole\EventRegister;
class EasySwooleEvent implements Event
{
public static function initialize()
{
date_default_timezone_set('Asia/Shanghai');
// 注冊(cè)自定義 `logger` 處理器
\EasySwoole\Component\Di::getInstance()->set(\EasySwoole\EasySwoole\SysConst::LOGGER_HANDLER, new \App\Log\LogHandler());
// 或使用如下方式進(jìn)行注冊(cè)自定義 `logger` 處理器
// \EasySwoole\EasySwoole\Logger::getInstance(new \App\Log\LogHandler());
}
public static function mainServerCreate(EventRegister $register)
{
}
}
注意:針對(duì) EasySwoole 3.4.x 之前版本,請(qǐng)?jiān)?bootstrap 事件(即項(xiàng)目根目錄的 bootstrap.php 文件)中,使用 \EasySwoole\EasySwoole\Logger::getInstance(new \App\Log\LogHandler()); 方式注冊(cè)自定義日志處理器。
日志中心
通常在一些情況下,會(huì)把數(shù)據(jù)往日志中心推送進(jìn)行數(shù)據(jù)分析,在 onLog 回調(diào),把日志信息,推送到日志中心即可。