核心是让应用将异常输出到 stdout/stderr,再通过 Docker 日志驱动统一收集过滤;需确保各语言框架禁用文件日志、启用控制台输出,并配合 grep 或结构化日志(如 JSON 格式 level 字段)精准捕获异常。

要捕获 Docker 容器日志中的异常,核心不是“写日志捕获代码”,而是让应用把异常输出到 stdout/stderr,再通过 Docker 日志机制统一收集和过滤。Docker 本身不解析日志内容,它只负责转发容器的标准输出流。
确保应用异常打到标准输出
很多语言默认把错误堆栈写到 stderr,但有些框架或配置会静默吞掉异常、写到文件、或重定向到其他地方。你需要确认:
- Java 应用避免只用
log4j2.xml写文件,需配ConsoleAppender并确保rootLogger.level = error - Python 的
logging.basicConfig()要设stream=sys.stderr,未捕获异常可用sys.excepthook打印到 stderr - Node.js 不要用
fs.appendFile写日志,改用console.error()或process.stderr.write() - Go 程序别用
log.SetOutput(file),直接用log.Println()或fmt.Fprintln(os.Stderr, ...)
用 docker logs 实时过滤异常关键词
Docker 原生命令适合简单排查,比如查看最近 100 行含 “Exception”、“ERROR”、“panic” 的日志:
docker logs --tail 100 myapp | grep -i -E "(exception|error|panic|traceback|failed)"
持续监听(Ctrl+C 退出):
docker logs -f myapp | grep -i "error"
注意:该方式不保留原始时间戳(除非容器日志本身带),且无法跨多容器聚合。
用日志驱动对接集中式日志系统
生产环境推荐用 json-file(默认)、syslog 或 fluentd 驱动,把日志发到 ELK、Loki 或 Datadog:
- 启动容器时指定驱动:
docker run --log-driver=fluentd --log-opt fluentd-address=localhost:24224 ... - 在 Fluentd 配置里加 filter 匹配异常字段:
@type grep; regexp key: log; pattern /Exception|ERROR/ - Loki 中可用 LogQL 查询:
{job="myapp"} |= "ERROR" |= "Exception"
在应用内做结构化异常日志(推荐)
比字符串匹配更可靠的方式是让应用输出 JSON 格式日志,并标记 level 字段:
{"level":"error","ts":"2024-06-10T14:22:31Z","msg":"failed to connect db","error":"timeout","stack":"..."}
这样可在日志系统中精确筛选 level == "error",避免误匹配 “error” 这个单词(比如 URL 中的 /error-page)。
多数语言有成熟库支持:Python 用 structlog,Go 用 zerolog 或 zap,Java 可配 Logback + logstash-logback-encoder。











