一、问题现象与背景
在使用loguru的critical方法进行关键错误日志记录时,开发者经常遇到PermissionError: [Errno 13] Permission denied的报错。这种情况通常发生在:
- 日志文件被其他进程锁定
- 运行Python脚本的用户缺乏写入权限
- SELinux或AppArmor等安全模块限制
- 文件系统只读挂载
二、根本原因分析
通过系统调用追踪发现,loguru的critical方法底层会执行以下敏感操作:
1. 尝试创建日志文件(open(O_CREAT))
2. 追加写入模式(open(O_APPEND))
3. 文件旋转(rename)操作
这些操作都需要相应的文件系统权限,特别是在生产环境中常见的/var/log目录,通常需要root权限才能写入。
三、七种解决方案
1. 修改目标目录权限
最直接的解决方法是通过chmod和chown命令调整权限:
sudo chmod 775 /var/log/myapp
sudo chown $USER /var/log/myapp
2. 使用用户可写目录
将日志文件存储在用户主目录或/tmp下:
logger.add("~/myapp.log") # 家目录
logger.add("/tmp/myapp.log") # 临时目录
3. 运行时提权
对于必须写入系统目录的情况:
import os
if os.geteuid() != 0:
os.execvp("sudo", ["sudo", "python3"] + sys.argv)
4. 配置loguru旋转策略
减少文件操作频率:
logger.add("app.log", rotation="100 MB")
5. 使用内存缓冲
延迟写入敏感位置:
logger.add("app.log", buffering=1024)
6. ACL高级权限控制
精细化的权限管理:
setfacl -m u:$USER:rw /var/log/myapp
7. 容器化解决方案
在Docker环境中:
volumes:
- ./logs:/var/log/myapp
四、高级调试技巧
当问题难以复现时:
- 使用
strace -f python script.py追踪系统调用 - 检查
/var/log/auth.log获取SELinux拒绝记录 - 通过
getfacl验证ACL权限
五、最佳实践建议
- 开发阶段使用相对路径日志
- 生产环境配置日志轮转
- 实现权限降级机制
- 监控日志写入异常
- 建立多级日志备份