laravel5日誌設定篇(3/3) – 精確到微秒及日誌輸出位置記錄
阿新 • • 發佈:2019-02-10
想要實現的功能
- 記錄日誌輸出時的時間精度到微秒
- 記錄日誌輸出時程式執行位置(方法/行數)
- 記錄程序ID
- app.log
[2017-10-22 10:13:57.833504] production.INFO: -- Startup {"method":"GET","uri":"/v1/stocks"} {"pid":7124,"line":"App\\Bootstrap\\ApplicationLog->startupLog:66"} [2017-10-22 10:13:57.898702] production.INFO: get stocks info {"pid":7124,"line":"App\\Http\\Controllers\\StocksController->index:66"} [2017-10-22 10:13:57.903274] production.INFO: -- Shutdown {"time":"70.371[ms]","memory":"2048[kb]"} {"pid":7124,"line":"App\\Bootstrap\\ApplicationLog->handleShutdownLog:81"}
- sql.log
[2017-10-22 10:11:19.750913] production.DEBUG: select count(*) as aggregate from `stocks_input` where `stocks_input`.`deleted_at` is null; {"time":0.63} {"pid":7124} [2017-10-22 10:11:19.752787] production.DEBUG: select * from `stocks_input` where `stocks_input`.`deleted_at` is null order by `created_at` desc limit 10 offset 0; {"time":0.83} {"pid":7124} [2017-10-22 10:11:19.756438] production.DEBUG: select * from `goods` where `goods`.`id` = 1 limit 1; {"time":0.9} {"pid":7124}
環境
- php 7.0.22
- laravel 5.2.*
具體實現
- 繼承
Illuminate\Log\Writer
類,複寫getDefaultFormatter
方法 - 編寫
Monolog
用處理模組 - 1步驟建立的類替換老Writer及註冊
Monolog
用處理模組
新Write類 (app/Utils/Writer.php)
<?php namespace App\Utils\Monolog; use Illuminate\Log\Writer as BaseWriter; use Monolog\Formatter\LineFormatter; /** * 時間精確到微秒 * * @package app.Utils.Monolog */ class Writer extends BaseWriter { /** * Get a default Monolog formatter instance. * * @return \Monolog\Formatter\LineFormatter */ protected function getDefaultFormatter() { return new LineFormatter(null, 'Y-m-d H:i:s.u', true, true); } }
Monolog輸出處理模組
- 程式執行位置資訊 (app/Utils/Monolog/Processor/IntrospectionProcessor.php)
<?php
namespace App\Utils\Monolog\Processor;
use Monolog\Logger;
/**
* Monolog用處理模組
* 標準IntrospectionProcessor的簡化版
*
* @package app.Utils.Monolog.Processor
*/
class IntrospectionProcessor
{
private $level;
private $skipClassesPartials;
public function __construct($level = Logger::DEBUG, array $skipClassesPartials = ['Monolog\\', 'Illuminate\\'])
{
$this->level = Logger::toMonologLevel($level);
$this->skipClassesPartials = $skipClassesPartials;
}
/**
* @param array $record
* @return array
*/
public function __invoke(array $record)
{
// return if the level is not high enough
if ($record['level'] < $this->level) {
return $record;
}
$trace = debug_backtrace();
// skip first since it's always the current method
array_shift($trace);
// the call_user_func call is also skipped
array_shift($trace);
$i = 0;
while (isset($trace[$i]['class'])) {
foreach ($this->skipClassesPartials as $part) {
if (strpos($trace[$i]['class'], $part) !== false) {
$i++;
continue 2;
}
}
break;
}
$line = null;
if (isset($trace[$i]['class'])) {
$line = $trace[$i]['class'];
if (isset($trace[$i]['class'])) {
$line = $line . '->' . $trace[$i]['function'];
}
} else if (isset($trace[$i - 1]['file'])) {
$line = $trace[$i - 1]['file'];
}
if (null !== $line && isset($trace[$i - 1]['line'])) {
$line = $line . ':' . $trace[$i - 1]['line'];
}
$record['extra']['line'] = $line;
return $record;
}
}
- 執行緒ID資訊 (app/Utils/Monolog/Processor/ProcessIdProcessor.php)
<?php
namespace App\Utils\Monolog\Processor;
/**
* Monolog用處理模組
* 標準IntrospectionProcessor的簡化版, 原輸出鍵值文字長度過長
*
* @package app.Utils.Monolog.Processor
*/
class ProcessIdProcessor
{
/**
* @param array $record
* @return array
*/
public function __invoke(array $record)
{
$record['extra']['pid'] = getmypid();
return $record;
}
}
替換老Writer及註冊Monolog
用處理模組 (app/Providers/LogServiceProvider.php)
<?php
namespace App\Providers;
// 引入新建立IntrospectionProcessor, ProcessIdProcessor, Writer類
use App\Utils\Monolog\Processor\IntrospectionProcessor;
use App\Utils\Monolog\Processor\ProcessIdProcessor;
use App\Utils\Monolog\Writer;
use Carbon\Carbon;
use Illuminate\Support\ServiceProvider;
use Monolog\Logger as Monolog;
/**
* 日誌記錄器服務
*
* @package app.Providers
*/
class LogServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('app-log', function () {
return $this->createAppLogger();
});
$this->app->singleton('sql-log', function () {
return $this->createSqlLogger();
});
}
/**
* Create the app logger.
*
* @return \Illuminate\Log\Writer
*/
public function createAppLogger()
{
//新增
$processors = [
new ProcessIdProcessor(),
new IntrospectionProcessor()
];
$log = new Writer(
new Monolog($this->channel(), [], $processors), $this->app['events']
);
$this->configureHandler($log, 'app');
return $log;
}
/**
* Create the sql logger.
*
* @return \Illuminate\Log\Writer
*/
public function createSqlLogger()
{
//新增
$processors = [
new ProcessIdProcessor(),
];
$log = new Writer(
new Monolog($this->channel(), [], $processors), $this->app['events']
);
$this->configureHandler($log, 'sql');
return $log;
}
...
檢視原文:https://www.huuinn.com/archives/343
更多技術乾貨:風勻坊
關注公眾號:風勻坊