Laravel日志出现权限问题的常见情况

背景

近期时不时会因为日志文件权限问题,抛出“failed to open stream: Permission denied”的异常。解决的办法可以无脑给这个文件、目录甚至整个项目授予777的权限,迅速解决问题,但是再迅速也得等人登上服务器去改一下权限,下次出现问题依然会导致服务中断。
我分析了一下,主要原因是有多个系统用户针对同一个日志文件进行操作。总结了一些复现的场景,希望能让你debug的时候你少踩点坑。这里只是针对日志文件场景,其他文件理论上是相通的。

laravel日志记录方式

laravel默认是以单个文件的形式存放到项目的 storage/logs/laravel.log 这个地方
如果你改成了按日期的,文件名就会使用 laravel-YYYY-MM-DD.log 这样子的格式生成。
如图这个例子,日志文件的拥有者有 root 以及 www-data
Laravel日志出现权限问题的常见情况
如果是按日期保存,你把全部文件777了,只能保证当前全部文件不会有问题。但是明天可能会有新的日志文件生成出来,这个新生成的文件权限未必是777的哦。这就很容易出现因为权限问题导致的无法写入。一旦某个用户(比如root)生成了今天的日志文件,那FPM就很可能无法写入。
如果是单个文件的形式保存,chmod 777 laravel.log 理论上可以快速解决。

可能存在的多用户写入场景

首先查看FPM的用户:

ps -aux |grep php

Laravel日志出现权限问题的常见情况
然后可以看到FPM用户是www-data,下面开始排查

1. 队列

laravel的队列一般是由Supervisor来维护,如果你用了队列,请检查运行队列监听命令的用户与FPM进程的用户是否一致。
Supervisor 配置文件通常存储在 /etc/supervisor/conf.d 目录。

Laravel日志出现权限问题的常见情况
需要注意的是Supervisor配置文件里 stdout_logfile 一般存放在 /var/log/supervisor/ 或你自己喜欢的路径,主要是记录在什么时间处理了什么任务,如果你在队列的执行过程中 echo 了一些信息也会写到这个日志,跟项目里 storage/logs/laravel.log 的日志不是一个东西,不要共用。
Laravel日志出现权限问题的常见情况

2. cli命令

cli命令主要包括

  • 你或你的同事使用root、ubuntu、ec2-user等用户登入服务器,在项目里执行php artisan XXXXX
  • 你或你的同事使用cron/crontab等工具调度,最后执行了php artisan XXXXX 等的项目命令
    如果是你或你的同事登入服务器操作,建议退出前去看一下日志的拥有者/权限。
    如果是通过cron/crontab方式运行的,那就需要检查运行命令的用户是否与FPM用户一致,如果不是需要修改成一样的。以我的www-data用户为例,使用crontab的定时任务查看:
    crontab -u www-data -l
    执行上面这个命令就会显示出www-data的定时任务,如果服务器有crontab的调度,但显示no crontab for www-data或者显示的全是#开头的,那大概率这里会导致的日志文件拥有者不一致。

3. 其他,说不定是同事坑你了

上面的2种场景应该是很常见的,你都确认了没有问题,就得结合你的服务器实际情况慢慢排查了,欢迎交流。

本作品采用《CC 协议》,转载必须注明作者和本文链接
Buffett-Cai
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

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