够意思博客够意思博客够意思博客

Easyswoole日志管理和Console远程控制台

日志处理

#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 = 1LOG_LEVEL_NOTICE = 2LOG_LEVEL_WARNING = 3LOG_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远程控制台

加载中~