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:
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.
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 []
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);
}
}
}
Laravel 5.7
Log Driver: syslog
// config/logging.php
'syslog' => [
'driver' => 'syslog',
'tap' => [ App\Logging\CustomizeFormatter::class ],
'level' => 'debug',
],
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],
],
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.