如何将PHP应用日志发送至无外网权限的AWS App Runner容器日志?
如何将AWS App Runner上的PHP应用日志接入App Runner应用日志?
问题描述
我有一个运行在AWS App Runner上的容器,内部部署了PHP应用。该容器无外网访问权限,也无法通过端点直接将日志发送至CloudWatch,因此希望利用App Runner提供的应用日志功能。目前Nginx日志已能正常上报,但尝试多种方式发送PHP应用日志均失败:
- 写入
/proc/1/fd/1因权限问题失败; - 直接日志上报因网络连接问题失败;
- 在启动脚本中通过
tail -f /var/log/file > /proc/1/fd/1 &运行后台任务在本地可行,但在App Runner中无效且无相关日志说明原因。
【编辑补充】还尝试通过supervisord将日志作为进程进行tail操作,配置如下:
[program:logging] command=/bin/tail -f /app/log/file.log stdout_logfile=/proc/1/fd/1 stdout_logfile_maxbytes=0 stderr_logfile=/proc/1/fd/1 stderr_logfile_maxbytes=0 priority=300
该方式在本地容器中可行,但在App Runner中依然无效。
解决方案
方案1:直接让PHP输出日志到stdout/stderr(最推荐)
App Runner的应用日志默认收集容器主进程的标准输出(stdout)和标准错误(stderr),无需额外转发逻辑:
- 修改
php.ini配置,将错误日志定向到stderr:error_log = /dev/stderr log_errors = On - 对于自定义业务日志,在PHP代码中直接输出到stdout:
file_put_contents('php://stdout', '业务日志内容: ' . $message . PHP_EOL); - 若使用PHP-FPM,同步调整其日志配置:
php_admin_value[error_log] = /dev/stderr php_admin_flag[log_errors] = On
这种方式完全适配App Runner的日志收集机制,不会出现权限或后台进程失效问题。
方案2:修复日志文件权限并调整转发逻辑
如果必须将PHP日志写入文件,按以下步骤调整:
- 确保日志文件权限正确:
在容器启动脚本中提前创建日志目录/文件,并赋予PHP进程所属用户读写权限:mkdir -p /app/log touch /app/log/file.log chown www-data:www-data /app/log/file.log - 避免后台运行转发进程:
App Runner会监控容器主进程,若主进程退出则重启容器。不要将tail命令后台运行(&),而是将其整合到主进程逻辑中:
或使用# 启动PHP-FPM后台运行 php-fpm -D # 启动Nginx前台运行 nginx -g "daemon off;" & # 持续tail日志到stdout,作为主进程的一部分 exec tail -f /app/log/file.logwait命令维持主进程存活:php-fpm -D tail -f /app/log/file.log & # 以Nginx作为前台主进程 nginx -g "daemon off;" wait
方案3:修正Supervisord配置
若坚持使用Supervisord,需调整配置适配App Runner环境:
- 让Supervisord自身日志输出到stdout:
在supervisord.conf的[supervisord]段添加:[supervisord] logfile=/dev/null logfile_maxbytes=0 stdout_logfile=/proc/1/fd/1 stdout_logfile_maxbytes=0 stderr_logfile=/proc/1/fd/1 stderr_logfile_maxbytes=0 - 调整日志转发的program配置:
使用绝对路径执行tail,并确保运行用户有权限访问日志文件:[program:php-log] command=/usr/bin/tail -f /app/log/file.log user=www-data stdout_logfile=/proc/1/fd/1 stdout_logfile_maxbytes=0 stderr_logfile=/proc/1/fd/1 stderr_logfile_maxbytes=0 autostart=true autorestart=true - 将Supervisord作为容器主进程:
容器的CMD/ENTRYPOINT需指定Supervisord前台运行:CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]-n参数确保Supervisord在前台运行,避免App Runner误判主进程退出。
额外排查点
- 检查App Runner控制台的日志配置,确认应用日志已开启,且日志级别设置正确(如INFO及以上)。
- 通过App Runner的临时会话功能进入容器,手动执行日志转发命令,排查是否有隐藏报错。
内容的提问来源于stack exchange,提问作者Rudiger
相关产品推荐
相关产品推荐

