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 时节省时间。如有问题,欢迎留言交流!

相关推荐
江华森1 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
迪菲赫尔曼1 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
by209993 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
螺丝钉tina3 小时前
[Playwright][08] Upload 模块自动化:如何设计真实业务测试用例?
运维·自动化·测试用例
迪菲赫尔曼3 小时前
【基础篇 12】把环境与源码接起来:检查 GPU,再安装服务器上的项目
运维·服务器·开发语言·人工智能·python·yolo·目标检测
cq林志炫3 小时前
两个Linux服务器之间同步文件
linux·运维·服务器
yyuuuzz4 小时前
云服务器安全组规则优先级的机制记录
运维·服务器·网络·安全·阿里云·aws
KaiwuDB4 小时前
KaiwuDB 运维实战06:数据库备份与恢复:从理论到实战
运维·数据库·时序数据库·kaiwudb
无人生还别怕4 小时前
如何搭建k8s服务(containerd部署)
linux·云原生·容器·kubernetes·openanolisos
知已难寻5 小时前
01 · OpenStack的认证管理 Keystone
运维·服务器·云原生·云计算·openstack