Laravel 5.5 以下版本中自定義日誌行為

麥索發表於2018-07-31

在 Laravel 5.6 版本中日誌行為可以很容易的進行自定義,而在5.5以下版本中日誌行為自定義自由度並不是很高,但是專案有需求不能因為這個就強行將專案升級為5.6吧,況且作為一個穩定的專案升級框架大版本有可能會有很多坑,基於這些原因我嘗試了對 Laravel 5.5 的日誌進行改造以適應我的需求。

Laravel 的日誌行為大部分是在 Illuminate\Log\LogServiceProvider 中,我們可以看一下其中的程式碼片段:

/**
 * Configure the Monolog handlers for the application.
 *
 * @param  \Illuminate\Log\Writer  $log
 * @return void
 */
protected function configureDailyHandler(Writer $log)
{
    $log->useDailyFiles(
        $this->app->storagePath().'/logs/laravel.log', $this->maxFiles(),
        $this->logLevel()
    );
}
複製程式碼

這是我最常在專案中使用的日誌儲存方式,可以看到日誌的儲存路徑幾近與寫死的狀態,無法通過外部引數輕易的更改。

最開始我想的是重寫這個 Provider 然後將其註冊到 app.phpproviders 陣列中,但是這種行為並不可行,因為通過檢視原始碼,LogServiceProvider 是在框架啟動時就註冊。

在 中有這樣一個方法控制了這個註冊行為:

protected function registerBaseServiceProviders()
{
    $this->register(new EventServiceProvider($this));

    $this->register(new LogServiceProvider($this));

    $this->register(new RoutingServiceProvider($this));
}
複製程式碼

既然我們知道了它們是如何生效的,那麼我們將這兩個類繼承並修改其中我們需要改變的行為進行改造,我的改造方式如下。在app\Providers中新建LogServiceProvider類繼承Illuminate\Log\LogServiceProvider,程式碼如下:

<?php


namespace App\Providers;

use Illuminate\Log\LogServiceProvider as BaseLogServiceProvider;
use Illuminate\Log\Writer;

class LogServiceProvider extends BaseLogServiceProvider
{
    /**
     * Configure the Monolog handlers for the application.
     *
     * @param  \Illuminate\Log\Writer  $log
     * @return void
     */
    protected function configureDailyHandler(Writer $log)
    {
        $path = config('app.log_path');
        $log->useDailyFiles(
            $path, $this->maxFiles(),
            $this->logLevel()
        );
    }
}
複製程式碼

config/app.php目錄中新增配置:

'log_path' => env('APP_LOG_PATH', storage_path('/logs/laravel.log')),
複製程式碼

app目錄中新建Foundation目錄,新建Application類繼承Illuminate\Foundation\Application類,重寫registerBaseServiceProviders方法。

<?php
/**
 * Created by PhpStorm.
 * User: dongyuxiang
 * Date: 2018/7/31
 * Time: 16:53
 */

namespace App\Foundation;

use App\Providers\LogServiceProvider;
use Illuminate\Events\EventServiceProvider;
use Illuminate\Routing\RoutingServiceProvider;
use Illuminate\Foundation\Application as BaseApplication;


class Application extends BaseApplication
{

    /**
     * Register all of the base service providers.
     *
     * @return void
     */
    protected function registerBaseServiceProviders()
    {
        $this->register(new EventServiceProvider($this));

        $this->register(new LogServiceProvider($this));

        $this->register(new RoutingServiceProvider($this));
    }

}
複製程式碼

說是重寫其實只是將use類換從了我們自己建立的LogServiceProvider

然後在bootstrap\app.php中將變數$appnew物件換成我們繼承重寫後的。

$app = new App\Foundation\Application(
    realpath(__DIR__.'/../')
);
複製程式碼

這樣我就成功的將日誌路徑可以隨便定義了,而且來說有了這次經驗我對於框架不符合我需求的地方可以做更進一步的優化以符合我的要求,而且我沒有更改框架底層的程式碼,當框架有bug修復的時候我也可以放心的進行框架更新。

相關文章