Laravel 7.x 生产不记录 HTTP 500 异常
Laravel 7.x Production Not Logging HTTP 500 Exception
Laravel 似乎存在一个长期存在的问题,即无法在生产环境中正确登录。我有一个使用 Docker-compose 制作 Web、队列和调度程序服务的小型应用程序。在生产环境中测试小应用程序(目前没有用户,所以我可以做一些中断调试而不用担心),我在尝试访问页面时遇到 HTTP 500 错误。检查我的 web/laravel.log 文件,过去一个月没有输出。我尝试删除日志文件,并再次点击页面的 500 错误。没有创建文件。
进入 Web 服务容器并 运行 修补并执行以下操作:
Log::debug("HELLO, World?");
创建了 Web/Laravel.log 文件,其中包含一行文本
[2020-08-19 17:51:36] production.DEBUG: HELLO, World?
所以有几件事:
- 每次 docker 重建,我的缓存、配置等都是从主机上的基础项目重建的,容器只有卷用于日志文件,所以这可能不是缓存或重置(我将在下面解释)。
Log::debug("message")
按预期工作的事实表明这不是 PATH 问题,也不是权限问题。
- 我只需要对我的队列服务进行大量调试,在此期间我经常使用 Queue/laravel.log 文件。据我所知,队列服务毫无问题地记录了异常。由于队列服务和 Web 服务是从完全相同的基础项目创建的,具有完全相同的步骤,唯一不同的是执行命令。
- 我尝试在我的开发环境中将 APP_DEBUG 和 APP_ENV 分别更改为 false 和生产环境,并且在我的开发环境中仍然得到正确的输出。
而且似乎有很多其他表格也有同样的问题,none 其中给出了正确的解决方案。使用 我能够看到错误消息
"Property [permissioned_users] does not exist on this collection instance."
然后很容易找到问题并解决。但是,如果我将来遇到 500 Issue,我希望它记录下来,这样我就知道发生了什么,所以我想彻底解决这个问题并追根究底。
此问题的以下线程未给出官方解决方案:
Laravel log errors in production
Laravel 5.8 Log levels are not working
App Debug Not Working in Laravel 5.8
Laravel 5.3 Logging not working
许多这些较旧的解决方案都建议设置“APP_LOG_LEVEL”,这似乎在 Laravel 5.6 中已贬值。 ( Unrelated - Reimplementation of this here? )
目前,我的解决方案似乎是将以下行添加到 App\Exception\Handler 第 37 行(而不是上面的 dd($e->getMessage() 首先帮助我进行调试):
if(config('app.env') == "production" && env('CONTAINER_ROLL') == "web-server"){ Log::error("PRODUCTION WEB EXCEPTION : " . $exception->getMessage()); }
但我更愿意找出根本问题并彻底解决这个问题。
在撰写此消息时,我发现了根本问题(权限问题)。请参阅下文了解我的具体 (Docker) 问题
这是一个 Docker 和权限问题。
在我的 Web-service Docker 文件中,我有以下行:
RUN chown -R www-data:www-data /app/storage/
检查我的 Web 服务的日志文件后,我发现了以下内容:
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 storage
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 app
drwxrwxr-x 1 www-data www-data 4096 Jun 11 08:15 framework
drwxr-xr-x 2 root root 4096 Aug 19 08:51 logs
-rw-r--r-- 1 root root 1353 Aug 20 03:13 laravel.log
运行 命令
chown -R www-data:www-data ./storage/logs/
问题已解决,re-hitting 我的 500 HTTP 错误出现在日志中!
任务完成!
补充说明 给仍然需要这部分解释的人。
Apache Web 服务器需要 www-data (dockerfile FROM php:7.4-apache)。 Apache 服务器 运行 PHP (laravel) 应用程序是 www-data,它需要写入日志文件的权限。我你BASH进入容器,你是运行作为root,所以如果你从Tinker执行Log::debug(),它将由root用户执行。对于队列和调度程序(dockerfile FROM php:7.4,运行 CRON 或 Artisan Worker),它们都以 root 用户身份执行,而不是 apache。
跟进此事,
我确实注意到了一些有趣的人工制品,并且能够重新创建它。问题是数量。 HOST VOLUME 文件将覆盖 Container 的文件,因此应用程序的文件(被复制到 Docker Container 中)将被覆盖而不受影响。另外值得注意的是,修改容器中的卷文件(包括所有权和权限)将修改主机上的卷文件,反之亦然。问题是我的 Host-side 卷文件web/laravel.log
最初拥有 root:root
所有权,它链接到 web-service 容器。因此,尽管对该文件执行 Dockerfile chown 命令,它仍将被该卷的主机文件覆盖,这将使其无法工作。 运行
chown -R www-data:www-data storage/logs/
在 web-service 容器内将主机文件修改为 www-data 的所有权。由于主机卷文件现在是 www-data 所有权,Docker-compose 重建和刷新从那里开始。但是,如果我退出容器(当容器仍然 运行 时)并对主机卷日志文件执行相反的命令
chown -R root:root logs/web/
(其中 web/laravel.log 存在),它会立即将 web-service 容器的文件(返回检查)再次更改为 root:root,这会停止 apache 的日志记录无法正常工作。
注意以下几点:
主机应用程序:
drwxrwxr-x 5 root www-data 4096 Jun 17 2019 storage
drwxrwxr-x 3 root www-data 4096 Jun 17 2019 app
drwxrwxr-x 6 root www-data 4096 Jun 11 08:15 framework
drwxrwxr-x 2 root root 4096 Nov 21 2019 logs
-rwxrwxr-x 1 root root 1657039 Jun 28 05:29 laravel.log <<<< Irrelevant due to Volume
主机网络容器:
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 storage
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 app
drwxrwxr-x 1 www-data www-data 4096 Jun 11 08:15 framework
drwxr-xr-x 2 www-data www-data 4096 Aug 20 05:21 logs
-rw-r--r-- 1 www-data www-data 19840 Aug 20 06:02 laravel.log <<<< Linked to Host by Volume
主机网络日志卷位置:
drwxr-xr-x 2 www-data www-data 4096 Aug 20 05:21 web
-rw-r--r-- 1 www-data www-data 19840 Aug 20 06:02 laravel.log <<<< Linked to Container by Volume
主机队列容器:
drwxrwxr-x 3 root root 4096 Jun 17 2019 app
drwxrwxr-x 1 root root 4096 Jun 11 08:15 framework
drwxr-xr-x 2 root root 4096 Jun 11 12:26 logs
-rw-r--r-- 1 root root 322662871 Aug 20 08:01 laravel.log <<<< Linked to Host by Volume
主机队列日志卷位置:
drwxr-xr-x 2 root root 4096 Jun 11 12:26 queue
-rw-r--r-- 1 root root 322662871 Aug 20 08:01 laravel.log <<<< Linked to Container by Volume
Laravel 似乎存在一个长期存在的问题,即无法在生产环境中正确登录。我有一个使用 Docker-compose 制作 Web、队列和调度程序服务的小型应用程序。在生产环境中测试小应用程序(目前没有用户,所以我可以做一些中断调试而不用担心),我在尝试访问页面时遇到 HTTP 500 错误。检查我的 web/laravel.log 文件,过去一个月没有输出。我尝试删除日志文件,并再次点击页面的 500 错误。没有创建文件。
进入 Web 服务容器并 运行 修补并执行以下操作:
Log::debug("HELLO, World?");
创建了 Web/Laravel.log 文件,其中包含一行文本
[2020-08-19 17:51:36] production.DEBUG: HELLO, World?
所以有几件事:
- 每次 docker 重建,我的缓存、配置等都是从主机上的基础项目重建的,容器只有卷用于日志文件,所以这可能不是缓存或重置(我将在下面解释)。
Log::debug("message")
按预期工作的事实表明这不是 PATH 问题,也不是权限问题。- 我只需要对我的队列服务进行大量调试,在此期间我经常使用 Queue/laravel.log 文件。据我所知,队列服务毫无问题地记录了异常。由于队列服务和 Web 服务是从完全相同的基础项目创建的,具有完全相同的步骤,唯一不同的是执行命令。
- 我尝试在我的开发环境中将 APP_DEBUG 和 APP_ENV 分别更改为 false 和生产环境,并且在我的开发环境中仍然得到正确的输出。
而且似乎有很多其他表格也有同样的问题,none 其中给出了正确的解决方案。使用
"Property [permissioned_users] does not exist on this collection instance."
然后很容易找到问题并解决。但是,如果我将来遇到 500 Issue,我希望它记录下来,这样我就知道发生了什么,所以我想彻底解决这个问题并追根究底。 此问题的以下线程未给出官方解决方案:
Laravel log errors in production
Laravel 5.8 Log levels are not working
App Debug Not Working in Laravel 5.8
Laravel 5.3 Logging not working
许多这些较旧的解决方案都建议设置“APP_LOG_LEVEL”,这似乎在 Laravel 5.6 中已贬值。 ( Unrelated - Reimplementation of this here? )
目前,我的解决方案似乎是将以下行添加到 App\Exception\Handler 第 37 行(而不是上面的 dd($e->getMessage() 首先帮助我进行调试):
if(config('app.env') == "production" && env('CONTAINER_ROLL') == "web-server"){ Log::error("PRODUCTION WEB EXCEPTION : " . $exception->getMessage()); }
但我更愿意找出根本问题并彻底解决这个问题。
在撰写此消息时,我发现了根本问题(权限问题)。请参阅下文了解我的具体 (Docker) 问题
这是一个 Docker 和权限问题。
在我的 Web-service Docker 文件中,我有以下行:
RUN chown -R www-data:www-data /app/storage/
检查我的 Web 服务的日志文件后,我发现了以下内容:
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 storage
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 app
drwxrwxr-x 1 www-data www-data 4096 Jun 11 08:15 framework
drwxr-xr-x 2 root root 4096 Aug 19 08:51 logs
-rw-r--r-- 1 root root 1353 Aug 20 03:13 laravel.log
运行 命令
chown -R www-data:www-data ./storage/logs/
问题已解决,re-hitting 我的 500 HTTP 错误出现在日志中!
任务完成!
补充说明 给仍然需要这部分解释的人。
Apache Web 服务器需要www-data (dockerfile FROM php:7.4-apache)。 Apache 服务器 运行 PHP (laravel) 应用程序是 www-data,它需要写入日志文件的权限。我你BASH进入容器,你是运行作为root,所以如果你从Tinker执行Log::debug(),它将由root用户执行。对于队列和调度程序(dockerfile FROM php:7.4,运行 CRON 或 Artisan Worker),它们都以 root 用户身份执行,而不是 apache。
跟进此事,
我确实注意到了一些有趣的人工制品,并且能够重新创建它。问题是数量。 HOST VOLUME 文件将覆盖 Container 的文件,因此应用程序的文件(被复制到 Docker Container 中)将被覆盖而不受影响。另外值得注意的是,修改容器中的卷文件(包括所有权和权限)将修改主机上的卷文件,反之亦然。问题是我的 Host-side 卷文件web/laravel.log
最初拥有 root:root
所有权,它链接到 web-service 容器。因此,尽管对该文件执行 Dockerfile chown 命令,它仍将被该卷的主机文件覆盖,这将使其无法工作。 运行
chown -R www-data:www-data storage/logs/
在 web-service 容器内将主机文件修改为 www-data 的所有权。由于主机卷文件现在是 www-data 所有权,Docker-compose 重建和刷新从那里开始。但是,如果我退出容器(当容器仍然 运行 时)并对主机卷日志文件执行相反的命令
chown -R root:root logs/web/
(其中 web/laravel.log 存在),它会立即将 web-service 容器的文件(返回检查)再次更改为 root:root,这会停止 apache 的日志记录无法正常工作。
注意以下几点:
主机应用程序:
drwxrwxr-x 5 root www-data 4096 Jun 17 2019 storage
drwxrwxr-x 3 root www-data 4096 Jun 17 2019 app
drwxrwxr-x 6 root www-data 4096 Jun 11 08:15 framework
drwxrwxr-x 2 root root 4096 Nov 21 2019 logs
-rwxrwxr-x 1 root root 1657039 Jun 28 05:29 laravel.log <<<< Irrelevant due to Volume
主机网络容器:
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 storage
drwxrwxr-x 1 www-data www-data 4096 Jun 17 2019 app
drwxrwxr-x 1 www-data www-data 4096 Jun 11 08:15 framework
drwxr-xr-x 2 www-data www-data 4096 Aug 20 05:21 logs
-rw-r--r-- 1 www-data www-data 19840 Aug 20 06:02 laravel.log <<<< Linked to Host by Volume
主机网络日志卷位置:
drwxr-xr-x 2 www-data www-data 4096 Aug 20 05:21 web
-rw-r--r-- 1 www-data www-data 19840 Aug 20 06:02 laravel.log <<<< Linked to Container by Volume
主机队列容器:
drwxrwxr-x 3 root root 4096 Jun 17 2019 app
drwxrwxr-x 1 root root 4096 Jun 11 08:15 framework
drwxr-xr-x 2 root root 4096 Jun 11 12:26 logs
-rw-r--r-- 1 root root 322662871 Aug 20 08:01 laravel.log <<<< Linked to Host by Volume
主机队列日志卷位置:
drwxr-xr-x 2 root root 4096 Jun 11 12:26 queue
-rw-r--r-- 1 root root 322662871 Aug 20 08:01 laravel.log <<<< Linked to Container by Volume