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() 所標註的方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章