Docker 多容器日志统一查看

背景

在生产环境中,我们常常会遇到一个服务部署了多个副本(容器)的情况。当服务出现异常(例如 Go 程序发生 panic)时,我们需要快速定位是哪个容器出了问题,并查看具体的堆栈信息。如果逐个容器执行 docker logs 再 grep,效率低下。本文介绍几种在宿主机上一次性查看所有相关容器日志并过滤 panic 的方法,尤其适合 Kubernetes 集群中的节点直接操作。


环境准备

首先,查看当前运行的容器,确认要监控的服务名称(这里以 backend 为例):

bash 复制代码
docker ps | grep backend

可以看到有多个容器运行,我们需要同时查看它们的日志 ,并过滤出包含 panic 的行。


方法一:一次性查看所有容器的近期日志并过滤 panic

适用场景:快速排查最近一段时间是否有 panic 发生,不需要持续监控。

命令

bash 复制代码
docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} sh -c 'echo "===== Container {} =====" && docker logs --tail 200 {} 2>&1' | grep -i panic -B 2 -A 5

命令拆解

  • docker ps --filter "name=backend" --format "{``{.ID}}"
    • --filter "name=backend":只筛选容器名中包含 backend 的容器(根据你的实际情况调整关键词)。
    • --format "{``{.ID}}":只输出容器 ID,便于后续处理。
  • xargs -I {}:将每个容器 ID 赋值给 {},然后执行后面的命令。
  • sh -c '...':执行一个 shell 命令串。
    • echo "===== Container {} =====":打印分隔线,标识当前日志来自哪个容器。
    • docker logs --tail 200 {} 2>&1:取每个容器最近 200 行日志,并将标准错误重定向到标准输出(因为 panic 可能输出到 stderr)。
  • grep -i panic -B 2 -A 5:忽略大小写匹配 panic,并显示匹配行的前 2 行和后 5 行,便于查看上下文堆栈。

输出效果

如果存在 panic,会显示类似:

复制代码
===== Container 2aa39b02c002 =====
[2026-08-28 10:23:45] panic: runtime error: invalid memory address
[2026-08-28 10:23:45] goroutine 123 [running]:
[2026-08-28 10:23:45] main.handleRequest(...)
...
===== Container 45fb08fe5cb5 =====
(无输出)

变形命令

  • 只看日志内容,不显示容器分隔符(适合进一步处理):

    bash 复制代码
    docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} docker logs --tail 500 {} 2>&1 | grep -i panic
  • 调整 --tail 行数(例如取最近 1000 行):

    bash 复制代码
    docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} sh -c 'echo "===== Container {} =====" && docker logs --tail 1000 {} 2>&1' | grep -i panic -B 3 -A 8
  • 如果不想限制行数,直接取全部日志(日志量巨大时慎用):

    bash 复制代码
    docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} sh -c 'echo "===== Container {} =====" && docker logs {} 2>&1' | grep -i panic -B 2 -A 5

方法二:实时跟踪所有容器的日志并过滤 panic

适用场景:持续监控,当新产生 panic 时立即看到。

命令

bash 复制代码
docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} docker logs -f {} 2>&1 | grep -i panic

说明

  • docker logs -f:类似 tail -f,持续输出新增日志。
  • 其他部分与方法一相同。
  • 按下 Ctrl+C 退出跟踪。

注意事项

  • 由于是实时输出,如果多个容器同时打印日志,可能会交错,但 grep 会过滤出所有包含 panic 的行,不会丢失。

  • 如果你想在实时输出中同时看到容器 ID,可以改进命令,但更为复杂。一般 panic 日志中会包含 goroutine 信息,足以定位问题。

  • 如果希望只跟踪最近一段时间内的日志(例如最近 10 分钟),可以添加 --since 10m:

    bash 复制代码
    docker ps --filter "name=backend" --format "{{.ID}}" | xargs -I {} docker logs -f --since 10m {} 2>&1 | grep -i panic

常见问题与注意事项

  1. 日志驱动问题 :如果 docker logs 没有输出,可能是容器使用了 journald 或 none 驱动。可以通过 docker inspect 查看日志驱动,然后改用 journalctl 查看。
  2. 容器过滤条件 :--filter "name=backend" 是基于容器名的部分匹配,如果你的容器名完全不同,请调整关键词。也可以使用 --filter "label=..." 等其他过滤方式。
  3. 新旧容器区分 :滚动更新时,新旧容器会同时存在一段时间。如果只关心最新版本,可以结合 --since 时间或容器启动时间来筛选。
  4. grep 大小写 :-i 参数可忽略大小写,确保匹配 panic、Panic、PANIC 等。
  5. 输出过多 :如果日志量极大,建议先取最近行数(--tail),避免终端卡死。

总结

  • 方法(xargs + docker logs --tail + grep) 适合快速回顾,一次性获取所有容器的近期 panic 信息。
  • 方法(xargs + docker logs -f + grep) 适合实时监控,持续跟踪新产生的 panic。

这两种方法都已在生产环境中验证有效,简单高效,无需额外安装工具。如果你还使用 Kubernetes,也可以结合 kubectl 或 stern 实现类似效果。

希望本文能帮助你在排查容器 panic 时节省时间。如有问题,欢迎留言交流!

相关推荐
凌云若寒13 小时前
BarTender提示#807错误:无法在拥有其他许可证的Licensing Service上激活节点锁定的 Professional 版许可证 的解决办法
运维·服务器·前端·学习·软件需求
Knight_AL13 小时前
PostgreSQL Docker 数据库备份:pg_dump 与 SQL 格式备份的区别
数据库·docker·postgresql
Julien200413 小时前
管理 Ansible 配置文件
linux·运维·服务器·ssh·学习方法
MicrosoftCloud13 小时前
性能排查 01|free 显示内存用了 90% 就是快满了吗?buff/cache 与 available 一次讲清
linux·运维·内存·free·buff/cache
灯澜忆梦14 小时前
【docker】#1 | Docker 初识
运维·docker·容器
风寄巴山秋14 小时前
OpenBMC:Web 页面功能异常排查
运维·服务器·前端·架构
小白的码BUG之路14 小时前
Jenkins -- 连接gitee
运维·gitee·jenkins
峥无15 小时前
Linux线程深度剖析:轻量级进程、虚拟内存分页、进程线程资源对比
linux·运维·mmap
骑着蜗牛撵大象32715 小时前
穿越 Docker 内核迷雾:镜像分层的叠加态与卷挂载的空间穿梭
运维·docker·容器·联合文件系统·卷挂载·镜像分层·存储驱动
honsor15 小时前
以太网温湿度传感器:RJ45直连机房的环境监控新方案
运维·网络·数据库·物联网·安全·云计算·github