swoft 学习之 踩坑笔记(二)

1.自定义 Debug 类

class Debug
{
    //日志显示类型
    const saveLogFile = true;       //保存到文件
    const viewOnConsole = true;     //显示在控制台

    /**
     * @param string $name 函数名
     * @param array $arguments 参数列表
     */
    private static function log($name, $arguments){
        $format = array_splice($arguments, 0, 1)[0];
        if (self::viewOnConsole) {
            $log = new CLog();
            if(method_exists($log, $name))
                CLog::$name($format, ...$arguments);
            else
                CLog::error('方法名(%s)不存在', $name);
        }

        if(self::saveLogFile){
            $log = new Log();
            if(method_exists($log, $name))
                Log::$name($format, ...$arguments);
            else
                Log::error('方法名(%s)不存在', $name);
        }
    }

    public function __call($name, $arguments){
        self::log($name, $arguments);
    }

    public static function __callStatic($name, $arguments){
        self::log($name, $arguments);
    }
}

测试的时候 发现 生成的记录 一直是在log 函数里面调用的

2020/04/29-14:16:00 [INFO] App\Tcp\Miscellany\Debug:log(24) minute(0) task run: 2020-04-29 14:16:00 

通过层层挖掘 发现swoft 的log 日志的层级是通过debug_backtrace()
获取的,然后发现一个有意思的代码块

    public function getTrace(string $message): string
    {
        $stackStr = '';
        $traces   = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        $count    = count($traces);

        if ($count >= 6) {
            $info = $traces[4];
            if (isset($info['file'], $info['class'])) {
                $class    = $info['class'];
                $lineNum  = $traces[3]['line'];
                $function = $info['function'];
                $stackStr = sprintf('%s:%s(%s)', $class, $function, $lineNum);
            }
        }

        if (!empty($stackStr)) {
            $message = sprintf('%s %s', $stackStr, $message);
        }

        return $message;
    }

果断将 $traces[4] 改成了 $traces[6],感觉世界一片宁静了

$info = $traces[6];
2020/04/29-14:34:24 [INFO] App\Tcp\Miscellany\TimerClass:minuteTask(24) minute(24) task run: 2020-04-29 14:34:24

没高兴一会儿,我又发现自己还是太年轻了,

2020/04/29-14:35:24 [INFO] App\Tcp\Miscellany\TimerClass:minuteTask(24) minute(24) task run: 2020-04-29 14:35:24 

Fatal error: Uncaught ErrorException: Undefined offset: 6 in /var/www/swoft/vendor/swoft/log/src/CLogger.php:91
Stack trace:
#0 /var/www/swoft/vendor/swoft/log/src/CLogger.php(91): Swoft\Error\DefaultErrorDispatcher->handleError(8, 'Undefined offse...', '/var/www/swoft/...', 91, Array)

系统提示,还有 CLog 和Log 类直接调用的方法再使用,并且直接调用他们的时候,$traces 没有6层调用,所以就得做如下变动
Clog 修改

namespace Swoft\Log\CLogger
90    $info = $traces[6]??$traces[4];
93    $lineNum  = $traces[5]['line']??$traces[3]['line'];
    public function getTrace(string $message): string
    {
        $stackStr = '';
        $traces   = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
        $count    = count($traces);

        if ($count >= 6) {
            $info = $traces[6]??$traces[4];
            if (isset($info['file'], $info['class'])) {
                $class    = $info['class'];
                $lineNum  = $traces[5]['line']??$traces[3]['line'];
                $function = $info['function'];
                $stackStr = sprintf('%s:%s(%s)', $class, $function, $lineNum);
            }
        }

        if (!empty($stackStr)) {
            $message = sprintf('%s %s', $stackStr, $message);
        }

        return $message;
    }

Log 修改内容

namespace Swoft\Log\Logger;
 407           $info = $traces[5]??$traces[3];

        if ($count >= 6) {
            $info = $traces[6]??$traces[4];
            if (isset($info['file'], $info['class'])) {
                $class    = $info['class'];
                $lineNum  = $traces[5]['line']??$traces[3]['line'];
                $function = $info['function'];
                $stackStr = sprintf('%s:%s(%s)', $class, $function, $lineNum);
            }
        }

这下是真的可以宁静了

2020/04/29-14:36:57 [INFO] App\Tcp\Controller\ChengduDeviceController:deviceRtdData(288) 客户端#1 编号(Y0028115200002) 上传实时数据,内容为:{"DataTime":1588142222,"W01":{"Avg":"0.0","Flag":"N"},"W02":{"Avg":"0","Flag":"N"},"T01":{"Avg":"0.0","Flag":"N"},"H01":{"Avg":"0.0","Flag":"N"},"PM25":{"Avg":"0","Flag":"N"},"PM10":{"Avg":"0","Flag":"N"},"B03":{"Avg":"0.0","Flag":"N"}}
2020/04/29-14:36:58 [INFO] App\Tcp\Miscellany\TimerClass:minuteTask(24) minute(58) task run: 2020-04-29 14:36:58 

2.Crontab 使用

在swoft v2.0 文档中有介绍

a. .env 文件中加入配置
CRONABLE=true
b. 注解类和注解定时方法
 * @Scheduled()
     * @Cron("0/2 * * * * *")

<定时小技巧>

  • / * * * * * * 表示每秒执行一次。
  • / 0 * * * * * 表示每分钟的第0秒执行一次,即每分钟执行一次。
  • / 0 0 * * * * 表示每小时的0分0秒执行一次,即每小时执行一次。
  • / 0/10 * * * * * 表示每分钟的第0秒开始每10秒执行一次。
  • / 10-20 * * * * * 表示每分钟的第10-20秒执行一次。
  • / 10,20,30 * * * * * 表示每分钟的第10,20,30秒各执行一次。
b. 配置启动方式

自启动

 return [
    'httpServer'     => [
            // ...
            'process' => [
                'crontab' => bean(Swoft\Crontab\Process\CrontabProcess::class)
            ],
            // ...
        ],
 ];

手动启动

$crontab = BeanFactory::getBean("crontab");
$crontab->execute("testCrontab", "method");
通过 Bean 容器拿到 crontab 管理器,然后直接使用 execute($beanName,$methodName) 方法,此方法有两个参数,$beanName 就是传入在 @Scheduled() 注解中设置的名字,$methodName 则是传入 @Scheduled() 标注的类中,@Cron() 所标注的方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章