日志处理
#Logger
在easyswoole3.2.3版本之后,easyswoole的默认日志处理类分离成了组件形式,组件地址:https://github.com/easy-swoole/log
#自定义日志
首先要定义好一个日志模板,需要继承并实现\EasySwoole\Log\LoggerInterface,如下:
<?php/** * Created by PhpStorm. * User: root * Date: 19-11-13 * Time: 上午11:00 */namespace App\Logger;use EasySwoole\Log\LoggerInterface;class Logger implements LoggerInterface{ function log(?string $msg, int $logLevel = self::LOG_LEVEL_INFO, string $category = 'DEBUG'): string { // TODO: Implement log() method. $date = date('Y-m-d H:i:s'); $levelStr = $this->levelMap($logLevel); $filePath = EASYSWOOLE_LOG_DIR."/".date('Y-m-d').".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 = 'DEBUG') { // TODO: Implement console() method. $date = date('Y-m-d H:i:s'); $levelStr = $this->levelMap($logLevel); $temp = $this->colorString("[{$date}][{$category}][{$levelStr}] : [{$msg}]",$logLevel)."\n"; fwrite(STDOUT,$temp); } private function colorString(string $str,int $logLevel) { switch($logLevel) { case self::LOG_LEVEL_INFO: $out = "[42m"; break; case self::LOG_LEVEL_NOTICE: $out = "[43m"; break; case self::LOG_LEVEL_WARNING: $out = "[45m"; break; case self::LOG_LEVEL_ERROR: $out = "[41m"; break; default: $out = "[42m"; break; } return chr(27) . "$out" . "{$str}" . chr(27) . "[0m"; } 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'; } }}
在EasySwooleEvent
中的 initialize
方法注入自定义日志处理, 如下:
public static function initialize(){ // TODO: Implement initialize() method. Di::getInstance()->set(SysConst::LOGGER_HANDLER, new \App\Logger\Logger());}
#logger调用方法
use use EasySwoole\EasySwoole\Logger;Logger::getInstance()->log('log level info',Logger::LOG_LEVEL_INFO,'DEBUG');//记录info级别日志//例子后面2个参数默认值Logger::getInstance()->log('log level notice',Logger::LOG_LEVEL_NOTICE,'DEBUG2');//记录notice级别日志//例子后面2个参数默认值Logger::getInstance()->console('console',Logger::LOG_LEVEL_INFO,'DEBUG');//记录info级别日志并输出到控制台Logger::getInstance()->info('log level info');//记录info级别日志并输出到控制台Logger::getInstance()->notice('log level notice');//记录notice级别日志并输出到控制台Logger::getInstance()->waring('log level waring');//记录waring级别日志并输出到控制台Logger::getInstance()->error('log level error');//记录error级别日志并输出到控制台Logger::getInstance()->onLog()->set('myHook',function ($msg,$logLevel,$category){ //增加日志写入之后的回调函数});
WARNING
注意,在非框架中使用,例如是单元测试脚本,请执行 EasySwoole\EasySwoole\Core::getInstance()->initialize(); 用于初始化日志
将输出/记录以下内容:
[2019-06-01 21:10:25][DEBUG][INFO] : [1] [2019-06-01 21:10:25][DEBUG][INFO] : [2] [2019-06-01 21:10:25][DEBUG][INFO] : [3] [2019-06-01 21:10:25][DEBUG][NOTICE] : [4] [2019-06-01 21:10:25][DEBUG][WARNING] : [5] [2019-06-01 21:10:25][DEBUG][ERROR] : [6] [2019-06-01 21:23:27][DEBUG][INFO] : [log level info] [2019-06-01 21:23:27][DEBUG2][NOTICE] : [log level notice] [2019-06-01 21:23:27][DEBUG][INFO] : [console] [2019-06-01 21:23:27][DEBUG][INFO] : [log level info] [2019-06-01 21:23:27][DEBUG][NOTICE] : [log level notice] [2019-06-01 21:23:27][DEBUG][WARNING] : [log level waring] [2019-06-01 21:23:27][DEBUG][ERROR] : [log level error]
WARNING
在新版logger处理方案中,新增了 LOG_LEVEL_INFO = 1
,LOG_LEVEL_NOTICE = 2
,LOG_LEVEL_WARNING = 3
,LOG_LEVEL_ERROR = 4
,4个日志等级,有助于更好的区分日志
#Trigger
\EasySwoole\EasySwoole\Trigger
触发器,用于主动触发错误或者异常而不中断程序继续执行。
在easyswoole3.2.3版本之后,easyswoole的默认Trigger类分离成了组件形式,组件地址:https://github.com/easy-swoole/trigger
例如在控制器的onException中,我们可以记录错误异常,然后输出其他内容,不让系统终端运行,不让用户发觉真实错误.
use EasySwoole\EasySwoole\Trigger;//记录错误异常日志,等级为ExceptionTrigger::getInstance()->throwable($throwable);//记录错误信息,等级为FatalErrorTrigger::getInstance()->error($throwable->getMessage().'666');Trigger::getInstance()->onError()->set('myHook',function (){ //当发生error时新增回调函数});Trigger::getInstance()->onException()->set('myHook',function (){ });
Console
Easyswoole 提供了一个基于tcp的基础远程控制台,方便用户做开发阶段的调试或者是线上的一些远程管理。
#安装
composer require easyswoole/console
#Server
use EasySwoole\Console\Console;use EasySwoole\Console\ModuleInterface;$http = new swoole_http_server("127.0.0.1", 9501);$http->on("request", function ($request, $response) { $response->header("Content-Type", "text/plain"); $response->end("Hello World\n");});/* * 开一个tcp端口给console 用 */$tcp = $http->addlistener('0.0.0.0',9600,SWOOLE_TCP);/* * 实例化一个控制台,设置密码为123456 */$console = new Console('myConsole','123456');/* * 定义自己的一个命令 */class Test implements ModuleInterface{ public function moduleName(): string { return 'test'; } public function exec(array $arg, int $fd, Console $console) { return 'this is test exec'; } public function help(array $arg, int $fd, Console $console) { return 'this is test help'; }}/* * 命令注册 */$console->moduleContainer()->set(new Test());/* * 依附给server */$console->protocolSet($tcp)->attachToServer($http);$http->start();
#Client
telnet 127.0.0.1 9600
#鉴权
auth {PASSWORD}
#执行命令
{MODULE} {ARG1} {ARG2}
#例子-如何在Easyswoole中实现日志推送
#模型定义
namespace App\Utility;use EasySwoole\Console\Console;use EasySwoole\Console\ModuleInterface;use EasySwoole\EasySwoole\Config;class LogPusher implements ModuleInterface{ public function moduleName(): string { return 'log'; } public function exec(array $arg, int $fd, Console $console) { /* * 此处能这样做是因为easyswoole3.2.5后的版本改为swoole table存储配置了,因此配置不存在进程隔离 */ $op = array_shift($arg); switch ($op){ case 'enable':{ Config::getInstance()->setConf('logPush',true); break; } case "disable":{ Config::getInstance()->setConf('logPush',false); break; } } $status = Config::getInstance()->getConf('logPush'); $status = $status ? 'enable' : 'disable'; return "log push is {$status}"; } public function help(array $arg, int $fd, Console $console) { return 'this is log help'; }}
#服务注册
重点是在easyswoole 全局的事件中进行注册
namespace EasySwoole\EasySwoole;use App\Utility\LogPusher;use EasySwoole\Console\Console;use EasySwoole\EasySwoole\Swoole\EventRegister;use EasySwoole\EasySwoole\AbstractInterface\Event;use EasySwoole\Http\Request;use EasySwoole\Http\Response;class EasySwooleEvent implements Event{ public static function initialize() { // TODO: Implement initialize() method. date_default_timezone_set('Asia/Shanghai'); } public static function mainServerCreate(EventRegister $register) { ServerManager::getInstance()->addServer('consoleTcp','9600',SWOOLE_TCP,'0.0.0.0',[ 'open_eof_check'=>false ]); $consoleTcp = ServerManager::getInstance()->getSwooleServer('consoleTcp'); /** 密码为123456 */ $console = new Console("MyConsole",'123456'); /* * 注册日志模块 */ $console->moduleContainer()->set(new LogPusher()); $console->protocolSet($consoleTcp)->attachToServer(ServerManager::getInstance()->getSwooleServer()); /* * 给es的日志推送加上hook */ Logger::getInstance()->onLog()->set('remotePush',function ($msg,$logLevel,$category)use($console){ if(Config::getInstance()->getConf('logPush')){ /* * 可以在 LogPusher 模型的exec方法中,对loglevel,category进行设置,从而实现对日志等级,和分类的过滤推送 */ foreach ($console->allFd() as $item){ $console->send($item['fd'],$msg); } } }); } public static function onRequest(Request $request, Response $response): bool { return true; } public static function afterRequest(Request $request, Response $response): void { // TODO: Implement afterAction() method. }}
#测试
链接远程服务器
telnet {IP} 9600
鉴权登录
auth 123456
打开日志推送
log enable
后续程序中的日志都会推送到你的控制台
日志处理官网文档:https://www.easyswoole.com/BaseUsage/log.html
Console远程控制台:https://www.easyswoole.com/Components/console.html
本文为够意思原创文章,转载无需和我联系,但请注明来自够意思博客blog.go1s.cn:够意思博客 » Easyswoole日志管理和Console远程控制台