Docker 日志管理
容器应用把日志写到标准输出,Docker 统一捕获,docker logs 即可查看。本章讲日志查看命令、json-file 驱动的轮转配置,以及容器内应用正确的打日志姿势。
docker logs 基础用法
docker logs 读取容器的 stdout/stderr 输出:-f 实时跟踪、--tail 只看末尾 N 行、--since/--until 按时间过滤:
docker logs myapp # 查看全部日志
docker logs -f --tail 100 myapp # 跟踪最新 100 行
docker logs --since 30m myapp # 最近 30 分钟
docker logs --since 2024-06-01T08:00:00 --until 2024-06-01T09:00:00 myapp
docker logs --timestamps myapp # 每行带时间戳
容器刚启动没有输出时加 -f 等即可;docker logs -f 只读输出,不像 attach 那样把输入接进容器。
日志原理:stdout/stderr 被重定向
容器内主进程写到标准输出/错误的内容会被守护进程捕获,落到宿主机 /var/lib/docker/containers/容器ID/ 下的 json 文件里,docker logs 只是回读该文件:
docker inspect --format '{{.HostConfig.LogConfig.Type}} {{.LogPath}}' myapp
# 输出:json-file /var/lib/docker/containers/ab12cd.../ab12cd...-json.log
所以容器内应用的正确做法是把日志打到 stdout/stderr(print、console.log、日志框架输出到控制台),而不是写进容器内文件——容器文件随容器销毁而丢,docker logs 也看不到。
json-file 驱动与轮转配置
默认驱动 json-file 若不加限制会无限增长吃满磁盘。在 /etc/docker/daemon.json 配置单文件大小与保留份数,重启 Docker 后对新容器生效:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
sudo systemctl restart docker # 修改 daemon.json 后必须重启守护进程
按容器单独配置
不想改全局时,docker run 时按容器指定即可;Compose 里对应 logging 字段:
docker run -d --log-opt max-size=5m --log-opt max-file=2 --name app myapp
services:
app:
image: myapp
logging:
driver: json-file
options:
max-size: "5m"
max-file: "2"
日志量再大时可让 filebeat/promtail 采集 json 日志送进 ELK/Loki 做集中检索。
常见问题速查
| 现象 | 原因与对策 |
|---|---|
| 日志文件无限膨胀 | 未配 max-size/max-file,按上文配置轮转 |
| docker logs 没有输出 | 应用把日志写进了文件而非 stdout/stderr |
| 时间戳看着不对 | json 日志内时间为 UTC,显示/收集时注意换算时区 |
| 多进程输出交错 | 一容器一主进程,多服务拆容器或用日志框架带请求号 |
小结
记住「应用写 stdout、Docker 负责收」:排查用 docker logs -f/--tail/--since,长期运行务必给 json-file 配 max-size 与 max-file 轮转,量再大就交给 ELK/Loki 集中管理。