php容器日志进elk实时监控的关键是:统一stdout/stderr为唯一日志出口,禁用php.ini中error_log文件路径,设为/dev/stderr;filebeat在宿主机监听/var/lib/docker/containers/*/-json.log,配置filestream类型、json.keys_under_root: true,并调优docker日志轮转。

直接说结论:PHP容器日志要进ELK并实时滚动监控,关键不是改PHP代码,而是让stdout成为唯一日志出口,再用filebeat从宿主机读取Docker JSON日志文件——绕过容器内安装Filebeat或挂载/var/log的常见坑。
PHP容器必须禁用error_log到文件,只输出到stderr/stdout
很多PHP镜像默认把error_log写进/var/log/php/error.log,但Docker无法自动捕获这类文件日志。一旦这么配,filebeat在宿主机上根本看不到内容。
- 在
php.ini里设error_log = /dev/stderr(或/dev/stdout),别留空、别写绝对路径 - Laravel/Lumen项目需关掉
storage/logs/写入:把LOG_CHANNEL=errorlog写进.env,并确保config/logging.php中errorlog驱动指向syslog或errorlog(它会自动转到stderr) - 验证方式:运行容器后执行
docker logs <container_id></container_id>,能看到PHP错误;再进容器ls -l /var/log/php/,应为空或不存在
filebeat必须从宿主机读/var/lib/docker/containers/**/*-json.log
Docker默认把每个容器的标准输出存为JSON格式日志文件,路径固定。在容器里装filebeat不仅臃肿,还会因权限和挂载问题失败;而用docker logs -f管道转发又不可靠、丢日志。
-
filebeat.inputs配置必须用type: filestream,而非log(旧版) -
paths写成["/var/lib/docker/containers/*/*-json.log"],注意末尾-json.log不能漏 - 加
json.keys_under_root: true和json.overwrite_keys: true,否则message字段嵌套在log下,Kibana里搜不到原始PHP错误行 - 如果宿主机启用了
systemd-journald,确认/etc/docker/daemon.json没设"log-driver": "journald"——这会让日志进journal,绕过JSON文件
Kibana里查PHP错误得过滤container.name和message字段
日志进了Elasticsearch后,默认message是完整JSON行,含时间戳、容器ID等,真正PHP报错藏在message子字段里。不调字段映射,搜索Parse error会匹配不到。
- 在Kibana > Stack Management > Index Patterns里,确认
filebeat-*索引模式已加载,且message字段类型是match_only_text或text(不是keyword) - 创建Discover视图时,在搜索栏输:
container.name:"my-php-app" and message:"Fatal error",双引号必须,避免分词干扰 - 若想高亮显示错误行,可在Kibana > Advanced Settings里开
queryBar.textBasedQueryEditor: true,用kuery语法更稳
最常被跳过的一步:Docker daemon日志大小限制会导致*-json.log被轮转删掉,filebeat就断档。务必在/etc/docker/daemon.json里加"log-opts": {"max-size": "10m", "max-file": "3"},再sudo systemctl restart docker——否则某天你会发现昨天的500错误全没了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











