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 集中管理。

笔记加载中…