直接监听 docker engine 事件流是最轻量及时的方式,通过 docker events 过滤 die/oom 事件并结合 inspect 判断 oomkilled 和退出码,实现精准根因分析与告警响应。

直接监听 Docker Engine 的事件流,是最轻量、最及时的方式。它不依赖轮询或日志解析,而是由守护进程主动推送状态变更,天然适配容器“短生命周期”的特性。
用 docker events 实时捕获退出事件
Docker 提供原生事件接口,可精准过滤 die(容器终止)和 oom(内存溢出)事件:
docker events \
--filter 'event=die' \
--filter 'event=oom' \
--format '{{json .}}' | \
while read event; do
echo "$event" | jq -r 'select(.Actor.Attributes.name) | "\(.time) \(.Actor.Attributes.name) exited with \(.Actor.Attributes.exitCode // "unknown")"' >> /var/log/container-exit.log
done
该脚本会持续输出类似:2026-08-13T14:22:05.123 web-api exited with 137
关键点:
-
--filter 'event=die'捕获所有容器终止事件(无论原因) -
--filter 'event=oom'单独捕获内核 OOM 杀死事件(部分版本需配合--filter 'type=container') -
jq提取容器名、时间、退出码,便于后续分析或告警
结合 exitcode 和 OOMKilled 字段做根因判断
仅靠事件不够,需进一步确认是否真因内存溢出:
# 查看某容器最新退出详情
docker inspect <container_id> | jq '.State | {ExitCode, OOMKilled, FinishedAt}'
# 示例输出:
# {
# "ExitCode": 137,
# "OOMKilled": true,
# "FinishedAt": "2026-08-13T14:22:05.123Z"
# }</container_id>
退出码 137 + OOMKilled: true 是 OOM 的铁证;若 OOMKilled: false 但 ExitCode 为 1,则大概率是应用崩溃。
对接告警与自动响应
事件流可直接接入通知链路:
- 推送到 HTTP 告警服务(如前面提到的
curl -X POST) - 写入本地文件后由 Filebeat 收集进 ELK
- 通过
grep -q "exitCode\":137"触发重启脚本(谨慎用于关键服务)
补充:避免漏掉已退出容器的离线诊断
对已停止容器,用以下命令快速回溯:
# 查看最近 10 个退出容器的退出码和 OOM 标记
docker ps -a --format "{{.ID}}\t{{.Status}}\t{{.Names}}" --filter "status=exited" | head -10 | \
while IFS=$'\t' read id status name; do
code=$(docker inspect "$id" --format='{{.State.ExitCode}}' 2>/dev/null)
oom=$(docker inspect "$id" --format='{{.State.OOMKilled}}' 2>/dev/null | tr '[:lower:]' '[:upper:]')
echo -e "$name\t$code\t$oom\t$status"
done | column -t
输出示例:api-gateway 137 TRUE Exited (137) 2 minutes ago
这种方式不依赖实时监听,适合巡检或故障复盘。
本质上,监控退出事件不是“查结果”,而是“等信号”——Docker daemon 就是那个最可信的信使。











