8

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

fab2s
  • 838
  • 2
  • 8
  • 14

2 Answers2

13

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

tanerkay
  • 3,819
  • 1
  • 19
  • 28
  • Thanks a lot, it's for sure not the way to go with containers, but it's very handy in good old physical servers – fab2s May 29 '18 at 19:47
8

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

Kundan roy
  • 3,082
  • 3
  • 18
  • 22
  • not good idea , you have to set log in all controller. – pankaj Oct 21 '20 at 18:43
  • @Kundan roy: Does this work with Lumen(incl. latest versions) too ? I don't see `config/logging.php` in Lumen, does this file have to be added manually ? – Vicky Dev Jul 25 '22 at 15:31