Laravel日志文件写入失败(permission denied)

用过Laravel的小伙伴一开始安装完框架后可能都遇到过daily 日志文件写入失败的问题,接下来咱们就来详细说下日志文件写入失败的缘由以及对应的解决方案。php

在讲这个问题以前可能须要简单介绍下Linux系统下的文件的Ownership和Permission。linux

  • Ownershiplaravel

    • User

      User是文件的全部者,默认状况下,用户建立了一个文件,该文件的全部者就是该用户。web

    • Group

      一个用户组能包含多个用户,全部属于这个组的用户都有相同的权限来访问文件。假设你有一个项目,不少用户都须要访问这个项目文件的权限,你不须要手动赋予这些用户全部权限,你只须要把这些用户加到一个组里面,赋予这些组有访问文件的权限,这样一来就仅仅只有组里面的成员能对文件进行读写操做。segmentfault

    • Other

      任何其余的用户都能访问文件,所以,给Other用户赋予权限,至关于全部用户都拥有这个权限。服务器

  • Permission框架

    在 UNIX/Linux 系统中每个文件和目录都有3中权限,如下就是对三个全部者的讨论。网站

    • Read:这个权限赋予你打开和读取文件的权限。拥有目录的读权限,你能列出其内容。
    • Write:拥有了读权限,你能修改文件的内容。拥有了目录的写权限,你能添加、移除以及重命名该目录下的文件。考虑一种场景,当你拥有文件的写权限,可是没有文件存储目录的写权限,你仍是能修改文件的内容,但不能重命名、移动以及移除目录下的文件。
    • Execute:在Windows系统中,一个可执行的程序一般都有.exe后缀,你能很方便的运行它。在 UNIX/Linux 中,除非被赋予可执行权限,不然你将不能运行该程序。若是未受权可执行权限,你让然能够看并修改程序代码(被授予读和写权限),可是没法运行它。

<div style="text-align:center;font-size:12px">linux下文件信息的显示截图</div>spa

<div style="text-align:center;font-size:12px">linux下目录的信息显示截图</div>debug

以上的截图显示了一个文件和文件夹的信息,咱们能够看到:

  • r 表明可读, w 表明可写, x 表明可执行。
  • 第一位文件显示 - ,文件显示 d
  • 上面第一张图片, rw-rw-r-— 中。第一组 rw- 表示文件的全部者对文件有可读、可写、不可执行的权限。第二组 rw- 表示文件所属的组内用户对该文件有可读、可写、不可执行的权限。第三组 r-— 表示其余任何用户对该文件有可读、不可写、不可执行的权限。
  • rw-rw-r-- 用二进制表示为 664 ,每一位若有权限则为 1 ,不然为 0 ,第一个三位 rw- 用二进制表示为 110 转化为十进制就是 6,后面两组依次类推,最后获得 664
  • 上面第一张图片的 dior www-data 表示该文件的全部者是 dior 用户,文件属于 www-data 组。

咱们知道不少应用系统中的日志是写文件的,且是以日期来命名文件的。因此第一次建立日志的用户就显得尤其重要,若是文件建立的 OnwerGroup 不对,其余的用户触发写入日志文件就会失败。

接下来咱们讨论下有多少种不一样的用户可能建立日志文件:

  • Crontab中执行的定时任务,跟建立 Crontab 的用户有关,此时建立的文件 OwnerGroup 值分别是该用户以及默认的 Group
  • 一些常驻的后台进程,好比Laravel中的 queue work ,此时建立的日志文件 OwnerGroup 值分别是执行该进程的用户以及所属的默认 Group
  • 正经常使用户访问网站产生的日志文件,此时建立的日志文件的 OwnerGroup 都是 www-datawww-data 用户是web服务器默认的用户。

由以上的分析,咱们大概已经找到了解决问题的方法。

  • 执行用户建立日志文件的权限为 664 比较恰当,这就须要当前用户的umask为 0002
  • 当前执行用户的默认 Group 应该设置为 www-data

下面就说下个人具体解决方案:

指定www-data用户执行crontab:

sudo crontab -u www-data -e

Laravel中修改建立日志文件的权限:

编辑 confog/logging.php 文件

添加 'permission' => 0664

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

你有什么更好的方法么?欢迎留言!

相关文章
相关标签/搜索