Docker 多容器日志统一查看

背景

在生产环境中,我们常常会遇到一个服务部署了多个副本(容器)的情况。当服务出现异常(例如 Go 程序发生 panic)时,我们需要快速定位是哪个容器出了问题,并查看具体的堆栈信息。如果逐个容器执行 docker logsgrep,效率低下。本文介绍几种在宿主机上一次性查看所有相关容器日志并过滤 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 没有输出,可能是容器使用了 journaldnone 驱动。可以通过 docker inspect 查看日志驱动,然后改用 journalctl 查看。
  2. 容器过滤条件--filter "name=backend" 是基于容器名的部分匹配,如果你的容器名完全不同,请调整关键词。也可以使用 --filter "label=..." 等其他过滤方式。
  3. 新旧容器区分 :滚动更新时,新旧容器会同时存在一段时间。如果只关心最新版本,可以结合 --since 时间或容器启动时间来筛选。
  4. grep 大小写-i 参数可忽略大小写,确保匹配 panicPanicPANIC 等。
  5. 输出过多 :如果日志量极大,建议先取最近行数(--tail),避免终端卡死。

总结

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

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

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

相关推荐
新时代牛马12 分钟前
异常向量与VBAR_ELx:Linux entry.S 中的vectors 布局
linux·运维·服务器
BlueAsia_Lab17 分钟前
华为 SuperCharge 认证,覆盖哪些产品?全品类梳理
运维·服务器·华为
H_oRIZoN_18 分钟前
Linux入门DAY32(文件 IO、进程、线程、IPC 通信)
linux·运维·服务器
0+11119 分钟前
Linux --Ext系列文件系统
linux·运维·服务器
潘正翔29 分钟前
Memcached构建缓存服务器
运维·服务器·数据库·缓存·云原生·memcached
叫我弓木吉1 小时前
从零开始:在宝塔面板上搭建你的专属隐私搜索引擎(SearXNG)
搜索引擎·docker·容器·开源·mango
攻城有术1 小时前
专项攻克——研发排查Linux各类问题命令+实战案例
linux·运维·服务器
小小克2 小时前
k8s控制器管理
云原生·容器·kubernetes
Acrellea2 小时前
当机柜功率冲向 50kW,配电运维如何跟上算力的进化速度?
大数据·运维