ログ周りの設定レシピ、3品。今回はその1品目。
- Laravel5.4 ログ周りの設定 1/3 開始・終了ログを残す(本記事)
- Laravel5.4 ログ周りの設定 2/3 クエリログを別ファイルで
- Laravel5.4 ログ周りの設定 3/3 ミリ秒に出力場所を添えて
やりたいこと
アプリケーションの開始・終了ログを残すようにします。
- 開始ログ:リクエストURLやバッチコマンドを出力
- 終了ログ:処理時間・使用メモリのピーク値を出力
laravel.log
[2017-06-17 10:16:11] local.INFO: -- Startup {"method":"GET","uri":"/log/sample?a=1&b=2"}
[2017-06-17 10:16:11] local.INFO: -- Shutdown {"time":"153.086[ms]","memory":"2048[kb]"}
[2017-06-17 10:16:19] local.INFO: -- Startup {"command":"php artisan list"}
[2017-06-17 10:16:19] local.INFO: -- Shutdown {"time":"383.189[ms]","memory":"6144[kb]"}
環境
Laravel 5.4.25
PHP 7.1.3
実装手順
- アプリケーションの開始・終了ログを残すクラスを作成
- Kernelクラスのbootstrappersプロパティに作ったクラスを登録します。(登録するクラスにはbootstrapメソッドが必要です。)
以下、サンプル。
一応動作確認はしていますが、サンプルをそのまま使う場合は自己責任で。
開始・終了ログを残すクラス
app\Bootstrap\ApplicationLog.php
<?php
namespace App\Bootstrap;
use Illuminate\Contracts\Foundation\Application;
/**
* include時の時間を取得しておく。
*/
if (!defined('APP_START_TIME')) {
define('APP_START_TIME', microtime(true));
}
/**
* アプリケーションログ設定クラス
*
* @package app.Bootstrap
*/
class ApplicationLog
{
/**
* 警告閾値:利用メモリ(MB)
*/
const THRESHOLD_WARNING_MEMORY = 100;
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* Bootstrap the given application.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public function bootstrap(Application $app)
{
$this->app = $app;
// テスト時はアプリケーションログなし
if (!$app->environment('testing')) {
// シャットダウンハンドラ追加:シャットダウンログ
register_shutdown_function([$this, 'handleShutdownLog']);
// 起動ログ
$this->startupLog();
}
}
/**
* 起動ログ
*/
public function startupLog()
{
if ($this->app->runningInConsole()) {
$command = sprintf('php %s', implode(' ', (array)array_get($GLOBALS, 'argv')));
$params = compact('command');
} else {
$method = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$params = compact('method', 'uri');
}
app('log')->info('-- Startup', $params);
}
/**
* シャットダウンログ
*
* @return void
*/
public function handleShutdownLog()
{
// シャットダウンログを出力
$time = $this->getProcessingTime();
$memory = $this->getPeekMemory();
if ($this->isOverUsingMemory(self::THRESHOLD_WARNING_MEMORY)) {
app('log')->warning('using a large amount of memory.', compact('memory'));
}
app('log')->info('-- Shutdown', compact('time', 'memory'));
}
/**
* 単位をつけて見やすくした時間を返す
*
* @param float $time マイクロ秒数
* @return string
*/
protected function formatTime($time)
{
if ($time < 1) {
return sprintf('%0.3f[ms]', $time * 1000);
} else if ($time < (1 / 1000)) {
return sprintf('%0.3f[μs]', $time * 1000 * 1000);
}
return sprintf('%0.3f[s]', $time);
}
/**
* 単位をつけて見やすくしたメモリを返す
*
* @param float $value
* @return string
*/
protected function formatMemory($value)
{
if ($value < 1024 * 10) {
// 10KBまではB表示
return sprintf('%s[b]', $value);
} else if ($value < (1024 * 1024 * 10)) {
// 10MBまではKB表示
return sprintf('%s[kb]', round($value / 1024, 1));
} else {
return sprintf('%s[mb]', round($value / (1024 * 1024), 2));
}
}
/**
* @param int $threshold 閾値(MB)
* @return bool
*/
protected function isOverUsingMemory($threshold)
{
return round(memory_get_peak_usage(1) / 1024 / 1024) > $threshold;
}
/**
* 処理時間を取得
*
* @return string
*/
protected function getProcessingTime()
{
return $this->formatTime(microtime(true) - APP_START_TIME);
}
/**
* メモリ使用量のピーク値を取得
*
* @return float
*/
protected function getPeekMemory()
{
return $this->formatMemory(memory_get_peak_usage(true));
}
}
Kernelクラスに登録
app\Http\Kernel.php
/**
* 親クラスからコピー
*/
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
// この一行を追加
\App\Bootstrap\ApplicationLog::class,
];
app\Console\Kernel.php
/**
* 親クラスからコピー
*/
protected $bootstrappers = [
\Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
\Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
\Illuminate\Foundation\Bootstrap\HandleExceptions::class,
\Illuminate\Foundation\Bootstrap\RegisterFacades::class,
\Illuminate\Foundation\Bootstrap\SetRequestForConsole::class,
\Illuminate\Foundation\Bootstrap\RegisterProviders::class,
\Illuminate\Foundation\Bootstrap\BootProviders::class,
// この一行を追加
\App\Bootstrap\ApplicationLog::class,
];
以上です。