Search code examples
laravellaravel-5monolog

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


My Goal

I'm willing to add the current authenticated user id to log lines (I'm using syslog driver) as a custom log formatting.

As part of my research, I've seen there are nice packages and tutorials to log user activity to database. But at least for now my intention is to move forward without extra packages and logging to syslog as I'm currently doing.

A typical log call in my app would look like:

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

I could also do something like:

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

It would be similar to what a documentation example suggests:

Docs Example

I'm currently doing this for certain lines, but since I'd like to have it in all log calls it would become like repeating myself every time I log something.

Desired Output

Current:

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

Desired:

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

My Approach

I have tried to tap the logger with success on changing the format, as suggested on docs.

But my current problem is that at the point the CustomizeFormatter class is excecuted, the Auth id seems not to be resolved just yet (not sure about this, but dd() returns null, so that's my guess):

<?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);
        }
    }
}

Setup

Laravel 5.7 Log Driver: syslog

    // config/logging.php

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

My Question(s)

  • Is there any way to resolve the auth user at this point, or any other approach to achieve this?

Solution

  • Based on the answer of DigitalDrifter and part of this post from Emir Karşıyakalı I managed to get a fair enough solution.

    I could not grab the User ID since (as per my understanding at this point) it can't be resolved just yet. But I felt satisfied with getting a more or less accurate client id and session id, so I can trace a user interaction thread on logs:

    <?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:

        // config/logger.php
    
        'syslog' => [
            'driver' => 'syslog',
            'level'  => 'debug',
            'tap'    => [App\Loggers\LocalLogger::class],
        ],
    

    Result

    Now I can get something like:

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

    or

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

    Depending on how I calculate the user/session ids.