Laravel 5 – Naming Logfiles According to OS User

Apologies in advance for the formatting of the code. WordPress is, basically, shit at handling any kind of formatting that is not its own flavour of HTML, so it plays all sorts of games reformatting and “improving” the layout. One day I’ll find a way through this mess.

I asked the question here on how to do this:

http://laravel.io/forum/06-02-2015-putting-os-username-into-log-file-name

The problem was that log files were being created by different OS users, depending on who was running Laravel (e.g. Apache user, cron user) and causing permissions problems. I am reproducing my answer here, as Laravel forums have a habit of being archived away as each new version is released.

So, here we go with the answer:

Okay, I think I have it now. It was quite a trek to find the answer. The result is that I have log files written by web access and by CLI under different names, looking like this:

laravel-apache2handler-2015-06-03.log
laravel-cli-2015-06-03.log

 

They are created by different users, and so don’t result in permission issues when writing to the files.

These are the steps needed in L5.0. I expect traits could have been used here, but I’ve extended classes instead. The steps are:

  1. Extend Illuminate\Foundation\Bootstrap\ConfigureLogging in my add, to add a new configureCustomHandler() handler method.
  2. Override the $bootstrappers arrays in Illuminate\Foundation\Console\Kernel and Illuminate\Contracts\Http\Kernel to point to my overridden ConfigureLogging.
  3. Set the “custom” logging method in app config.

In each of the steps that follow, I’ve tried to explain what is happening, and why. Laravel has a habit of moving things around quite often and changing how things work, so hopefully the explanations will help you to seek out what you will need to do when things move on and my steps are not quite right.

Step 1 is creating the new custom logging method.

In my app I created this class:

namespace App\Bootstrap;

use Illuminate\Log\Writer;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Foundation\Bootstrap\ConfigureLogging as BaseConfigureLogging;

class ConfigureLogging extends BaseConfigureLogging {

    protected function configureCustomHandler(Application $app, Writer $log)
    {
        $log->useDailyFiles(
            $app->storagePath().'/logs/laravel-'.php_sapi_name().'.log',
            $app->make('config')->get('app.log_max_files', 5)
        );
    }
}

It is all in the App namespace, so no messing was needed in composer to extend autoloading. The custom method is a copy of the configureDailyHandler() method in the parent class, with php_sapi_name() inserted into the logfile name.

So this goes into app/Bootstrap/ConfigureLogging.php

Step two involves telling Laravel to use this overridden class during bootstrap. The base bootstrap classes are here:

Illuminate\Foundation\Http\Kernel
Illuminate\Foundation\Console\Kernel

But you don’t touch those. The overrides for these are here:

App\Console\Kernel
App\Http\Kernel

So you can copy anything from the base kernel classes to the app kernel classes and make changes to them. This this case we copy the $bootstrapper properties, and change them as shown below:

For the console kernel:

    protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        //'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'App\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        'Illuminate\Foundation\Bootstrap\SetRequestForConsole',
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

For the http kernel:

    protected $bootstrappers = [
        'Illuminate\Foundation\Bootstrap\DetectEnvironment',
        'Illuminate\Foundation\Bootstrap\LoadConfiguration',
        //'Illuminate\Foundation\Bootstrap\ConfigureLogging',
        'App\Bootstrap\ConfigureLogging',
        'Illuminate\Foundation\Bootstrap\HandleExceptions',
        'Illuminate\Foundation\Bootstrap\RegisterFacades',
        'Illuminate\Foundation\Bootstrap\RegisterProviders',
        'Illuminate\Foundation\Bootstrap\BootProviders',
    ];

All we have done in both cases is remove the Illuminate ConfigureLogging bootstrap class and put in our override.

Final step three. What we have done so far is add a custom logger that is a tweak on one of the built-on loggers. However, we are not yet using it. Everything so far continues to run as it normally does (at least, it should, if no mistakes have been made).

Our custom logger handler method is called configureCustomHandler() and that makes the logger method “custom”. We could call it what we like: method “foobar” would need a handler configureFoobarHandler(). Simple.

So in config/app.php we find an entry:

'log' => 'daily',

That runs the configureDailyHandler(). Just change that entry to “custom”:

'log' => 'custom',

And that’s it. The new custom log handler will be used, with the new log file names.

No comments yet.

Leave a Reply