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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With