如何将授权用户 ID 或会话添加到登录 Laravel 5.7?

How to add auth user id or session to logging in Laravel 5.7?

我的目标

我愿意将当前经过身份验证的用户 ID 添加到日志行(我正在使用系统日志驱动程序)作为自定义日志格式。

作为我研究的一部分,我看到有很好的软件包和 tutorials 可以将用户 activity 登录到数据库。但至少现在我的意图是在没有额外包的情况下继续前进,并像我目前所做的那样记录到 syslog

我的应用程序中的典型日志调用如下所示:

logger()->info("Listing all items");

我也可以这样做:

$uid = Auth::id();
logger()->info("Listing all items for {$uid}");

这与文档示例所建议的类似:

我目前正在对某些行执行此操作,但由于我想在所有日志调用中使用它,所以每次我记录某些内容时都会重复自己。

期望的输出

当前:

Dec 10 23:54:05 trinsic Laravel[13606]: local.INFO: Hello world []

期望:

Dec 10 23:54:05 trinsic Laravel[13606]: local.INFO [AUTH_USER_ID=2452]: Hello world []

我的方法

我已经尝试点击记录器并成功更改格式,as suggested on docs

但我目前的问题是,在执行 CustomizeFormatter class 时,Auth id 似乎尚未解析(对此不确定,但 dd() returns 为空,这是我的猜测):

<?php

namespace App\Logging;

use Illuminate\Support\Facades\Auth;
use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    /**
     * Customize the given logger instance.
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        $authUser = Auth::id(); // null

        foreach ($logger->getHandlers() as $handler) {
            $formatter = new LineFormatter("%channel%.%level_name% [AUTH={$authUser}]: %message% %extra%");
            $handler->setFormatter($formatter);
        }
    }
}

设置

Laravel 5.7 日志驱动程序:syslog

    // config/logging.php

    'syslog' => [
        'driver' => 'syslog',
        'tap' => [ App\Logging\CustomizeFormatter::class ],
        'level' => 'debug',
    ],

我的问题

尝试将请求对象作为构造函数参数传递给您的自定义格式化程序 class,然后从那里访问用户:

<?php

namespace App\Logging;

use Illuminate\Support\Facades\Auth;
use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    public $request;

    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    /**
     * Customize the given logger instance.
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        $authUser = $this->request->user();
        foreach ($logger->getHandlers() as $handler) {
            $formatter = new LineFormatter("%channel%.%level_name% [AUTH={$authUser->id}]: %message% %extra%");
            $handler->setFormatter($formatter);
        }
    }
}

根据 DigitalDrifter 的回答和 this post from Emir Karşıyakalı 的一部分,我设法得到了一个足够公平的解决方案。

我无法获取用户 ID,因为(根据我目前的理解)它目前还无法解决。但我对获得或多或少准确的客户端 ID 和会话 ID 感到满意,因此我可以在日志上跟踪用户交互线程:

<?php

namespace App\Loggers;

use Monolog\Formatter\LineFormatter;

class LocalLogger
{
    private $request;

    public function __construct(\Illuminate\Http\Request $request)
    {
        $this->request = $request;
    }

    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter($this->getLogFormatter());
        }
    }

    protected function getLogFormatter()
    {
        $uniqueClientId = $this->getUniqueClientId();

        $format = str_replace(
            '[%datetime%] ',
            sprintf('[%%datetime%%] %s ', $uniqueClientId),
            LineFormatter::SIMPLE_FORMAT
        );

        return new LineFormatter($format, null, true, true);
    }

    protected function getUniqueClientId()
    {
        $clientId = md5($this->request->server('HTTP_USER_AGENT').'/'.$this->request->ip());
        $sessionId = \Session::getId();

        return "[{$clientId}:{$sessionId}]";
    }
}

配置:

    // config/logger.php

    'syslog' => [
        'driver' => 'syslog',
        'level'  => 'debug',
        'tap'    => [App\Loggers\LocalLogger::class],
    ],

结果

现在我可以得到类似的东西:

Dec 11 13:54:13 trinsic Fimedi[13390]: [2018-12-11 16:54:13] c6c6cb03fafd4b31493478e76b490650 local.INFO: Hello world

Dec 11 13:55:44 trinsic Fimedi[13390]: [2018-12-11 16:55:44] [c6c6cb03fafd4b31493478e76b490650:xUs2WxIb3TvKcpCpFNPFyvBChE88Nk0YbwZI3KrY] local.INFO: Hello world

取决于我如何计算 user/session 个 ID。