Laravel日志文件权限问题

8

如果在运行 php artisan 命令时发生错误,日志文件将会创建如下:

 -rw-rw-r-- 1 user www-data 2,2K Jul 28 18:08 laravel-2019-07-28.log

如果在使用Web浏览器应用程序时出现错误,日志文件将会像这样被创建:

-rw-r--r-- 1 www-data www-data 2,2K Jul 28 16:10 laravel-2019-07-28.log

www-data创建了原始文件后,如果php artisan命令出现错误,它会抛出一个Permission denied的错误,因为它无法写入日志。

是否有一种方法可以设置新创建文件的默认chmod,以便它们始终具有对群组的rw权限?或者您们有其他解决方案。

要重现此问题:

  1. 删除所有storage/logs/*.log文件
  2. 调用一些不存在的php artisan命令,例如:php artisan make:xy -> 这将产生一个错误并创建一个.log文件
  3. 在浏览器中调用路由/logout -> 这将尝试写入同一日志文件并抛出一个无法写入日志'Permission denied'的错误。

1
似乎你正在以不同的用户身份运行Artisan和Web服务器。 - PtrTon
当然了...你如何以www-data用户身份运行artisan命令? - lewis4u
你尝试过sudo -u www-data php artisan吗? - Tom Mulkins
1
我没有这样做过,那样可能会创建一个www-data用户的文件,但是使用sudo -u www-data php artisan运行似乎有点麻烦,你不这么认为吗? - lewis4u
1
对我来说,当在后台执行时,队列失败了,因为后台工作程序由于权限问题无法登录日志文件。在“config/logging.php”文件的日志通道(daily-channel)中添加“permission”=> 0755后,它就可以正常工作了。 - Charden Daxicen
4个回答

12

我曾经为这个问题苦苦挣扎,和提问者一样想知道:

有没有办法设置新创建的文件默认权限为 rw group

答案是

config/logging.php中,我添加了permission => 0666,这个可以在Laravel文档中找到,所以我的日志配置现在看起来像这样:

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

为了明确,0664已足以将群组权限设置为rw,但仍导致了权限错误。

0666已经解决了我的权限冲突。希望这能帮助到某些人!


2
谢谢,这在laravel 5.8上有效(我添加了'permission' => 0775) - Charden Daxicen
1
我关注 @ChardenDaxicen,他正在我的 CentOS 上工作。 - bravohex
最终,在 Laravel 8 上成功了。谢谢。 - Rizaldi Maulidia

4

在我的项目中,我通过定义一个自定义的记录器来解决这个问题,该记录器为每个用户名创建一个日志文件。

  1. Create the custom logger on app/Logging/UserNamedLogger.php:

    <?php
    
    
    namespace App\Logging;
    
    use Monolog\Handler\RotatingFileHandler;
    use Monolog\Handler\SyslogHandler;
    use Monolog\Logger;
    
    class UserNamedLogger
    {
        /**
         * Create a custom Monolog instance.
         *
         * @param  array  $config
         * @return \Monolog\Logger
         */
        public function __invoke(array $config)
        {
            $logger = new Logger('UserNamedLogger');
    
            // Configure Monolog to log on user named log files
            $filename = storage_path('logs/laravel-'.  posix_getpwuid(posix_geteuid())['name'] .'.log');
            $rotatingHandler = new RotatingFileHandler($filename);
            $logger->pushHandler($rotatingHandler);
    
            return $logger;
        }
    }
    
    
  2. Edit the config/logging.php config file:

'channels'键中添加您的自定义记录器:
    'named' => [
        'driver' => 'custom',
        'via' => App\Logging\UserNamedLogger::class,
    ],

将默认日志记录器更改为named通道:

    'default' => env('LOG_CHANNEL', 'named'),

现在,每次您的artisan(或计划任务)运行时,它将在不同于您的www服务器的文件上记录日志。这解决了权限问题。

在我看来,这应该是Laravel日志记录的默认行为。


非常有趣的解决方案,因此创建的每个日志文件都存储在单独的文件中,不会与用户权限发生冲突? - lewis4u
完全正确,@lewis4u。您可以使用类似的代码做一些很酷的事情。如果您喜欢这个答案,请考虑接受它! - Elias Soares
还要感谢您的编辑。我是在手机上写的,不幸的是stackoverflow没有移动端的代码样式按钮。 - Elias Soares
这个适用于Laravel 5.3吗?请回复! - Mohal
是的,没错。我在一个 Laravel 5.8 应用程序中使用了同样的解决方案。 - Elias Soares

1
更改 /var/www 文件夹的所有者: sudo chown www-data:www-data /var/www(如果您的项目在 /var/www 文件夹下)
如果您需要为不同的用户进行更改,可以将 www-data 替换为相应的用户级别,如 root

这样行不通。问题在于日志文件是每天的,如果一天中第一条日志消息来自www-data,则artisan将无法记录任何内容。如果artisan是第一个写入日志消息的,则同样适用。 - Elias Soares
这对我来说是有效的,因为这个命令是用来改变项目文件夹所有文件的拥有者。你可以试一下。如果我还错了请纠正我。 - Manohar Khadka
文件是以运行php的用户创建的。当您将php artisan作为某个用户名运行时,日志文件将属于该用户名,而不是www-data。(除非是root,否则php无法使用其他用户名创建文件) - Elias Soares
@EliasSoares 是正确的。 这只适用于在日志中已经有文件的情况,而不是对于新创建的文件! - lewis4u

1

对于那些不想要任何额外代码的人,只需通过命令行/终端进入laravel存储文件夹并运行以下3个命令:

设置默认组为www-data

find logs -type d -exec chgrp www-data {} +

将当前目录中创建的所有新文件和子文件夹设置为继承该目录的组

find logs -type d -exec chmod g+s {} +

如果用户创建文件,它将具有rw-rw-r权限。
sudo setfacl -R -d -m u::rw logs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接