Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 486
NiRR Avatar asked Oct 09 '22 13:10

NiRR


2 Answers

Laravel version 5.6.10 and later has support for a permission element in the configuration (config/logging.php) for the single and the daily driver:

    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => 'debug',
        'days' => 7,
        'permission' => 0664,
    ],

No need to juggle with Monolog in the bootstrap script.

Specifically, support was added in https://github.com/laravel/framework/commit/4d31633dca9594c9121afbbaa0190210de28fed8.

like image 161
crishoj Avatar answered Oct 12 '22 02:10

crishoj


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.

like image 76
Mysteryos Avatar answered Oct 12 '22 02:10

Mysteryos