我想向我的 Laravel 应用程序中的所有日志记录添加一些数据。
我认为知道当前用户的用户名和/或客户端 IP 地址会很有帮助。
目前我正在通过以下方式手动添加它:
Log::info('Pre-paid activation.', array('username' => Auth::user()->username));
但我想知道如何添加侦听器或其他东西以使所有日志记录器都具有用户名(如果可用)。
由于Laravel与 Monolog 一起开箱即用,因此非常简单。可以通过编辑app/start/global.php
并在开头的行之后添加以下内容来轻松实现Log::useFiles
:
Log::useFiles(storage_path().'/logs/laravel.log');
$monolog = Log::getMonolog();
$monolog->pushProcessor(function ($record) {
$record['extra']['user'] = Auth::user() ? Auth::user()->username : 'anonymous';
$record['extra']['ip'] = Request::getClientIp();
return $record;
});
基本上,我们使用底层的 Monolog 实例来注册一个处理器,该处理器将拦截任何要写入的日志记录。结果将类似于以下内容:
[2014-04-12 23:07:35] local.INFO:预付费激活。[] {"用户":"匿名","ip":"::1"}
关于 Monolog 处理器的更多信息:https ://github.com/Seldaek/monolog/blob/master/doc/01-usage.md#using-processors
额外:硬编码extra
是告诉 Monolog 添加数据作为额外的信息(多余的说)。在实践中,这是为了避免覆盖原始日志调用中添加的任何上下文数据。
在 Laravel 5 中,你可以通过自定义 Monolog 来实现。首先创建一个自定义 Monolog 的类,以便将用户信息添加到日志记录中:
namespace App\Logging;
use App\Models\User;
use Illuminate\Foundation\Application;
use Illuminate\Http\Request;
use Illuminate\Log\Logger;
class AddUserInformation
{
protected $request;
public function __construct(Request $request = null)
{
$this->request = $request;
}
public function __invoke(Logger $logger)
{
if ($this->request) {
foreach ($logger->getHandlers() as $handler) {
$handler->pushProcessor([$this, 'processLogRecord']);
}
}
}
public function processLogRecord(array $record): array
{
$record['extra'] += [
'user' => $this->request->user()->username ?? 'guest',
'ip' => $this->request->getClientIp()
];
return $record;
}
}
然后通过将类添加到config/logging.php
文件中的通道设置将类连接到 Laravel 记录器:
// ...
'channels' => [
'single' => [
'driver' => 'single',
'tap' => [\App\Logging\AddUserInformation::class],
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
// ...
]
对于那些寻找 laravel 7.x 的人,官方文档https://laravel.com/docs/7.x/logging#customizing-monolog-for-channels对此进行了解释
编辑 config\logging.php 并将其添加到您要登录的频道:
use Illuminate\Support\Facades\App;
...
'stack' => [
...
'tap' => [App\Logging\CustomizeFormatter::class],
],
然后创建文件 App\Logging\CustomizeFormatter.php
<?php
namespace App\Logging;
use Monolog\Formatter\LineFormatter;
class CustomizeFormatter
{
public function __invoke($logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new LineFormatter('custom logging - %level_name% %message% %context% %extra%'));
}
}
}