Unix 的 tail
命令可以用來檢視檔案的,例如檢視 2019-09-26
的最後 100 行日誌
$ cd storage/logs
$ tail -100 laravel-2019-09-26.log
將 tail
封裝成 artisan
指令,可實現命令列快速檢視日誌,spatie/laravel-tail 擴充套件包實現了該功能,類似功能實現如下。
建立命令
$ php artisan make:command LaravelTailCommand
需要做兩部分的功能:
- 獲取最新的日誌檔案;
- 轉化成終端的命令執行;
獲取最新的日誌檔案
依賴注入 Filesystem
use Illuminate\Filesystem\Filesystem;
.
.
.
class LaravelTailCommand extends Command
{
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
}
獲取全部日誌檔案
/**
* 獲取全部日誌檔案
*
* @return array
*/
public function allLogFiles() : array
{
return $this->files->allFiles(storage_path('logs'));
}
判斷某個日誌檔案是否為 laravel
日誌檔案
use SplFileInfo;
.
.
.
/**
* 是否為 Laravel 日誌檔案
*
* @param SplFileInfo $file
* @return boolean
*/
public function isLaravelLogFile(SplFileInfo $file) : bool
{
return strpos($file->getBaseName(),'laravel') !== false;
}
獲取最新的日誌檔案
/**
* 獲取最新的日誌路徑
*
* @return string | false
*/
public function findLatestLogFile()
{
$logFile = collect($this->allLogFiles())
->filter(function(SplFileInfo $file){
return $this->isLaravelLogFile($file);
})
->sortByDesc(function (SplFileInfo $file) {
return $file->getMTime();
})
->first();
return $logFile
? $logFile->getPathname()
: false;
}
轉化成終端的命令執行
預設顯示 100 行,且預設只顯示日誌摘要,不顯示詳情
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'tail
{--lines=100 : 輸出行數}
{--stack : 是否顯示詳細資訊,預設為不顯示}';
對於是否顯示詳情的處理
/**
* 根據引數來判斷是否顯示詳情
*
* @return null | string
*/
public function getFilters()
{
return $this->option('stack')
? null
: '| grep -i -E "^\[[0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\]" --color';
}
最終處理
use Symfony\Component\Process\Process;
.
.
.
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$latestLogPath = $this->findLatestLogFile();
$lines = $this->option('lines');
$filters = $this->getFilters();
$tail = "tail -n {$lines} -f ".escapeshellarg($latestLogPath)." {$filters}";
$process = new Process($tail);
$process->setTty(true)->run();
}
完整程式碼
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use SplFileInfo;
use Symfony\Component\Process\Process;
class LaravelTailCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'tail
{--lines=100 : 輸出行數}
{--stack : 是否顯示詳細資訊,預設為不顯示}';
/**
* The console command description.
*
* @var string
*/
protected $description = '快速檢視最新日誌';
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new command instance.
*
* @return void
*/
public function __construct(Filesystem $files)
{
parent::__construct();
$this->files = $files;
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$latestLogPath = $this->findLatestLogFile();
$lines = $this->option('lines');
$filters = $this->getFilters();
$tail = "tail -n {$lines} -f ".escapeshellarg($latestLogPath)." {$filters}";
$process = new Process($tail);
$process->setTty(true)->run();
}
/**
* 根據引數來判斷是否顯示詳情
*
* @return null | string
*/
public function getFilters()
{
return $this->option('stack')
? null
: '| grep -i -E "^\[[0-9]{4}\-[0-9]{2}\-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\]" --color';
}
/**
* 獲取全部日誌檔案
*
* @return array
*/
public function allLogFiles() : array
{
return $this->files->allFiles(storage_path('logs'));
}
/**
* 是否為 Laravel 日誌檔案
*
* @param SplFileInfo $file
* @return boolean
*/
public function isLaravelLogFile(SplFileInfo $file) : bool
{
return strpos($file->getBaseName(),'laravel') !== false;
}
/**
* 獲取最新的日誌路徑
*
* @return string | false
*/
public function findLatestLogFile()
{
$logFile = collect($this->allLogFiles())
->filter(function(SplFileInfo $file){
return $this->isLaravelLogFile($file);
})
->sortByDesc(function (SplFileInfo $file) {
return $file->getMTime();
})
->first();
return $logFile
? $logFile->getPathname()
: false;
}
}
使用
$ php artisan tail
$ php artisan tail --stack
$ php artisan tail --lines=500
本作品採用《CC 協議》,轉載必須註明作者和本文連結