laravel5.5 PHP指令碼執行Linux語句

2020-08-14 19:09:34

爲了方便自己檢視每天記錄的日誌,寫了一個PHP指令碼。
場景是這樣的:在laravel專案裏面storage/logs目錄下,每天會記錄請求第三方介面的日誌,但是請求的第三方有多個,並且每個第三方請求的日誌都會記錄到一個檔案中,例如2020-08-14請求四個第三方,那麼在laravel-2020-08-14.log中就會記錄這四個第三方的請求日誌,和第三方返回的介面資訊。
1、laravel指令碼用的是任務排程。執行下面 下麪的命令,會在app/console/commands目錄下,建立一個GetLog.php檔案

php artisan make:command GetLog

2、指令碼的內容如下

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class GetLog extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'get:log';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '獲取日誌檔案中指定產品的指定內容';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $this->getLogInfo();
    }

    /**
     * 獲取日誌檔案中的內容
     */
    private function getLogInfo(){
        //獲取昨天日誌檔名稱
        $logName = 'laravel-'.date("Y-m-d",strtotime("-1 day")).'.log';
        //獲取產品日誌查詢語句
        $selectSql = $this->getProductSelectSql($logName);
        foreach($selectSql as $key => $value){
            exec($value, $result, $var);
            if($var != 0){
                continue;
            }
            //去除返回結果左右空格
            foreach($result as $res_k => $res_v){
                $result[$res_k] = trim($res_v,' ');
            }
            //將結果記錄到指定目錄
            $monolog = \Log::getMonolog();
            $monolog->popHandler();
            $logPath = 'logs/logscount/'.date('Y-m-d').'.log';
            \Log::useFiles(storage_path($logPath),'info');
            \Log::info([$key=>$result]);
            //刪除每次執行的結果,否則當前執行的查詢會追加到上次執行的結果集裏面
            unset($result);
        }
    }

    /**
     * 獲取每個產品查詢日誌的語句
     * @param  string   $logName        [待查詢的日誌檔名稱]
     * @return array    $selectSql      [產品查詢日誌語句]
     */
    private function getProductSelectSql($logName){
        // grep 'jz' storage/logs/laravel-2020-08-13.log | grep -v '請求成功' | awk '{split($4,a,"message");print a[2]}' | sort | uniq -c | sort -rn
        // grep 'xy' storage/logs/laravel-2020-08-13.log | awk '{split($4,a,"errStr");split(a[2],b,",");print b[1]}' | sort | uniq -c | sort -rn
        // grep 'ms' storage/logs/laravel-2020-08-13.log | grep -v 'S00001' | grep -v 'S00000' | awk '{split($4,a,"message");split(a[2],b,",");print b[1]}' | sort | uniq -c | sort -rn
        // grep 'tc' storage/logs/laravel-2020-08-13.log | grep -v '成功' | grep 'respMsg' | awk '{split($4,a,"respMsg");print a[2]}' | sort | uniq -c | sort -rn
        $selectSql = [
            'jz' => "grep 'jz' storage/logs/$logName | grep -v '請求成功' | awk "."'{split($4,a,".'"message"'.");print a[2]}'"." | sort | uniq -c | sort -rn",
            'xy' => "grep 'xy' storage/logs/$logName | awk "."'{split($4,a,".'"errStr"'.");split(a[2],b,".'","'.");print b[1]}'"." | sort | uniq -c | sort -rn",
            'ms' => "grep 'ms' storage/logs/$logName | grep -v 'S00001' | grep -v 'S00000' | awk "."'{split($4,a,".'"message"'.");split(a[2],b,".'","'.");print b[1]}'"." | sort | uniq -c | sort -rn",
            'tc' => "grep 'tc' storage/logs/$logName | grep -v '成功' | grep 'respMsg' | awk "."'{split($4,a,".'"respMsg"'.");print a[2]}'"." | sort | uniq -c | sort -rn"
        ];
        return $selectSql;
    }
}

3、指令碼裏面的核心內容,就是 PHP exec含糊的使用,請參考官方文件  php 函數