关于 Laravel 日志权限

有时候 laravel 会出现无权限写日志的问题,我们可以按以下步骤去检查:

  1. 运行 laravel 的 php-fpm 是什么用户,一般是 www/nobody,不要使用 root。
  2. laravel 项目中的 storage/logs 目录 www/nobody 用户是否有读写权限。
  3. 是否有运行 crontab/supervisor/laravel 脚本,切运行的用户是否是 www/nobody。注意!如果以其他身份(例如root)运行脚本,laravel 可能会创建当天的日志文件,那这个日志文件是属于其他用户的,www/nobody 用户无法写入。

解决办法

  1. 修改 php-fpm 的配置文件,修改 user 和 group 为 www/nobody。
  2. chmod a+w storage/logs
  3. 运行任何 laravel 的脚本需要注意运行的用户,supervisor可以设置用户,crontab 可以加在 www/nobody 用户下。手动运行脚本可以 su www/nobody。
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 6年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 19
LOST

日志权限的问题基本是出现在有使用 artisan 执行定时任务的情况下。查看日志文件的权限时发现,处理 Web 请求时的日志的用户为 nobody。

$ ls -l
total 12508
-rw-r--r-- 1 nobody nobody    67680 Jan 14 23:59 laravel-2018-01-14.log
-rw-r--r-- 1 nobody nobody    74680 Jan 15 23:59 laravel-2018-01-15.log
-rw-r--r-- 1 nobody nobody    74680 Jan 16 23:59 laravel-2018-01-16.log

后来查了一下,使用 crontab 执行定时任务时,默认用户是 root,root 用户生成的文件,nobody 用户自然没有权限进行处理,出问题也就不奇怪了。又查了一下,使用 crontab 编辑定时任务列表的时候,是可以指定用户的,默认是编辑 root 用户的任务列表。

执行 crontab -e 的时候添加 -u 选项,并追加相应的用户名,就可以为指定的用户编辑定时任务列表。

$ crontab -u nobody -e

* * * * * edit the command you want to execute for user nobody

执行 crontab -u nobody -l 选项可以查看 nobody 用户的任务列表。

$ crontab -u nobody -l

* * * * * command one for user nobody
* * * * * command two for user nobody
6年前 评论
zouyan 4年前
zouyan 4年前
crawlerdlg 4年前
LOST

日志权限的问题基本是出现在有使用 artisan 执行定时任务的情况下。查看日志文件的权限时发现,处理 Web 请求时的日志的用户为 nobody。

$ ls -l
total 12508
-rw-r--r-- 1 nobody nobody    67680 Jan 14 23:59 laravel-2018-01-14.log
-rw-r--r-- 1 nobody nobody    74680 Jan 15 23:59 laravel-2018-01-15.log
-rw-r--r-- 1 nobody nobody    74680 Jan 16 23:59 laravel-2018-01-16.log

后来查了一下,使用 crontab 执行定时任务时,默认用户是 root,root 用户生成的文件,nobody 用户自然没有权限进行处理,出问题也就不奇怪了。又查了一下,使用 crontab 编辑定时任务列表的时候,是可以指定用户的,默认是编辑 root 用户的任务列表。

执行 crontab -e 的时候添加 -u 选项,并追加相应的用户名,就可以为指定的用户编辑定时任务列表。

$ crontab -u nobody -e

* * * * * edit the command you want to execute for user nobody

执行 crontab -u nobody -l 选项可以查看 nobody 用户的任务列表。

$ crontab -u nobody -l

* * * * * command one for user nobody
* * * * * command two for user nobody
6年前 评论
zouyan 4年前
zouyan 4年前
crawlerdlg 4年前

@LOST 写的非常好啊~可以写篇文章了,我这个记的比较简陋,并没有详细说明原因。
Laravel 的文档中也推荐使用 supervisor 了,这个也有用户权限问题,我就懒得详细写啦

6年前 评论
LOST

@allencao 我也是使用了 supervisor,添加定时任务指定了用户之后,就再也没有出现日志权限的问题了。另外,supervisor 在管理任务的时候,也是可以指定用户的。

6年前 评论
gitxuzan

nice 感谢,最近就出现这种问题 , 用了crontab 执行计划任务, 默认root 创建了日志, 导致普通日志写不进去

6年前 评论

@GitHacking 不用谢~我也是碰到问题,随手记录的,互相学习~

6年前 评论

我是用Linux命令 umask 来改的默认文件权限

5年前 评论

@LOST 我也是用的 supervisor,cron 配置是这样:

[root@izw5p7wt4dkfb7z app.test.com]# crontab -u www -l
* * * * * /usr/local/php/bin/php /data/wwwroot/app.test.com/artisan schedule:run >> /data/wwwroot/app.test.com/storage/logs/schedule.log 2>&1

但是这样的 cron 配置不执行,这条任务放在 root 下面确是可以执行的,请问这是什么情况?

5年前 评论
LOST

@Kevinvinvin

www 用户有 logs 目录下的写权限吗?

5年前 评论

@LOST 我找到问题了,看了一下日志,当使用 www 身份执行的时候报错了:

(www) CMD (/usr/local/php/bin/php /data/wwwroot/app.test.com/artisan schedule:run >> /data/wwwroot/app.test.com/storage/logs/schedule.log 2>&1)

(CRON) ERROR chdir failed (/home/www): No such file or directory

但是我不知道这该怎么解决:joy:

5年前 评论
七月羽歌 4年前
LOST

@Kevinvinvin

我对 crontab 的实现不太了解,比较不解的是,处理任务的过程中,为什么会执行 chdir 这个命令呢?你的任务代码中有这种操作吗?

错误提示是说, /home 目录下没有 www 的用户目录,这种虚拟用户没有这个目录也正常,所以感觉这只是问题的表象,不是根本。你可以再查查,可能有其他原因。

5年前 评论

@LOST 这条错误日志是因为在 /etc/crontab 中加了一条任务:

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
* * * * * www /usr/local/php/bin/php /data/wwwroot/app.test.com/artisan schedule:run >> /data/wwwroot/app.test.com/storage/logs/schedule.log 2>&1

指定了一个www用户,然后就有了这个错

5年前 评论
LOST

@Kevinvinvin

这些内容,确定是必须的吗?

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

指定了 SHELL,可能会产生切换目录的操作吧(我猜的),你尝试一下删掉这些配置,看看有没有效果,chdir 这个操作错误应该就能避免了吧。

5年前 评论

@LOST 我在/home目录下手动加了一个www目录,现在cron是可以正常执行了,并且生成的schedule.log文件是www的。但是supervisor的执行结果不符合预期,配置文件是这样的:

[program:queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /data/wwwroot/app.test.com/artisan queue:work --tries=2
autostart=true
autorestart=true
user=www
numprocs=8
redirect_stderr=true
stdout_logfile=/data/wwwroot/app.test.com/storage/logs/queue-worker.log

supervisor重启的时候会生成rootqueue-worker.log这个文件,队列里面写的日志laravel-2018-12-18.log也是root的:cold_sweat:

5年前 评论
LOST

你可以用 htop 命令查看每个进程的执行情况,看一下是哪个用户在执行该命令。

stdout_logfile=/data/wwwroot/app.test.com/storage/logs/queue-worker.log

这个配置项,是在重启 supervisor 时生成一个空的日志文件,并不是实际处理队列任务时创建的文件,所以文件所属 root 并不奇怪。

队列里面写的日志laravel-2018-12-18.log也是root的

至于这一点,会不会是有其他 root 用户执行的进程也在写日志?

5年前 评论

在5.6里增加了一个permission权限配置,可以试试

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

这几天也碰到了这个问题,真的是很折腾.....

4年前 评论

larave5.6.10 后支持通道中权限的声明 (permission)

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

使用这种办法也可以解决

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!