Search code examples
laravel-4file-permissions

Laravel daily log created with wrong permissions


I have a script that I run using php artisan (with root user), and sometimes it causes the daily log file to be created before the apache www-data user does - which means that when a real user uses my web application, I get the folder permission error:

Failed to open stream: Permission denied

I change the permissions back to www-data everytime but I want to solve this by having the log file always created with the correct permissions.

I've considered creating a cron job that creates the file or touches it to make sure it has the right permission everyday, but I'm looking for a better solution that doesn't rely on another script.

We've also considered wrapping php artisan in another script to make sure that it is always run with the www-data credentials, but somethings that we want to do are actually root procedures that apache should not be allowed to do.

Any more suggestions?


Solution

  • IMPORTANT This answer is incompatible with laravel 5.5+. Please see this answer: Custom (dynamic) log file names with laravel5.6

    Let's start with what is constant.

    You have a php artisan command, run by root.

    It is safe to assume that this command is executed daily.

    Solution No 1:

    Given that the user that creates the files is the one that has the permission to write to it by default, we can separate the logs by user as such:

    App/start/global.php

    /*
    |--------------------------------------------------------------------------
    | Application Error Logger
    |--------------------------------------------------------------------------
    |
    | Here we will configure the error logger setup for the application which
    | is built on top of the wonderful Monolog library. By default we will
    | build a basic log file setup which creates a single file for logs.
    |
    */
    
    Log::useDailyFiles(storage_path().'/logs/laravel-'.posix_getpwuid(posix_geteuid())['name'].'.log');
    

    If your www-data user were to create an error log, it would result in: storage/logs/laravel-www-data-2015-4-27.log.

    If your root user were to create an error log, it would result in: storage/logs/laravel-root-2015-4-27.log.

    Solution No 2:

    Change the log used by your artisan command, in your php script.

    In your run() function, add this line at the start:

    Log::useFiles(storage_path().'/logs/laravel-'.__CLASS__.'-'.Carbon::now()->format('Y-m-d').'.log');
    

    If your class's name is ArtisanRunner, then your log file will be:

    storage/logs/laravel-ArtisanRunner-2015-4-27.log.

    Conclusion: Solution number 1 is better, given that it delineates your logs by user, and hence no errors will occur.

    EDIT: As pointed out by jason, get_current_user() returns the script's owner name. Hence, for solution no.1 to apply, chown your artisan class files to the required username.