Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom (dynamic) log file names with laravel5.6

With laravel 5.5 we had access to configureMonologUsing() method in $app which made it possible for things like this in bootstrap/app.php:

$app->configureMonologUsing(function (Monolog\Logger $monolog) {
    $processUser = posix_getpwuid(posix_geteuid());
    $processName= $processUser['name'];

    $filename = storage_path('logs/laravel-' . php_sapi_name() . '-' . $processName . '.log');
    $handler = new Monolog\Handler\RotatingFileHandler($filename);
    $monolog->pushHandler($handler);
});

Doing this is useful when your app may be called from different contexts (eg CLI/HTTP) with different users (which is desirable) and file rotation. Doing this prevents write errors in case the log file was created by the HTTP user before the CLI one tries to add something in it and vice-versa.

Handling this is otherwise tricky or insecure as it involves to be able to set write perms on files that may not exist yet.

In addition, it's quite handy to have logs separated by contexts as they usually have little in common and it makes it easier to search among them.

Unfortunately, this way of doing things is not possible anymore with laravel 5.6 and I could not (yet) find a way to transparently do so for all file based logging.

Thanks

like image 794
fab2s Avatar asked May 12 '18 10:05

fab2s


2 Answers

Customisation is now done through invoking a custom formatter for Monolog.

Here is an example using daily rotating filenames (as I do).

This can be setup in config/logging.php, note the non-default tap parameter:

'channels' => [

    'daily' => [
        'driver' => 'daily',
        'tap' => [App\Logging\CustomFilenames::class],
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
    ],

]

In your custom formatter, you can manipulate the Monolog logger however you wish, similar to configureMonologUsing():

app\Logging\CustomFilenames.php

<?php

namespace App\Logging;

use Monolog\Handler\RotatingFileHandler;

class CustomFilenames
{
    /**
     * Customize the given logger instance.
     *
     * @param  \Illuminate\Log\Logger  $logger
     * @return void
     */
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            if ($handler instanceof RotatingFileHandler) {
                $sapi = php_sapi_name();
                $handler->setFilenameFormat("{filename}-$sapi-{date}", 'Y-m-d');
            }
        }
    }
}

One way to restore your original behaviour is to remove the {date} component from the handler's filenameFormat. A better way might be to manipulate the appropriate handler for the single driver.

See: https://laravel.com/docs/5.6/logging#advanced-monolog-channel-customization

like image 69
tanerkay Avatar answered Sep 23 '22 14:09

tanerkay


Solution:

step1: create a channel inside the config/logging.php file

example :

'channels' => [
    'single' => [
    'driver' => 'single', 
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
],

'web' => [
      'driver' => 'single',
      'path' => storage_path('logs/web/web.log'),
   ],

]

Step2: Now set dyanamic path from controller like this

config(['logging.channels.web.path' => storage_path('logs/web/'.time().'.log')]);

Step3 : now generate your log

  Log::channel('web')->info("your message goes here");

Enjoy :)

like image 45
Kundan roy Avatar answered Sep 24 '22 14:09

Kundan roy