Appearance
日志管理
默认日志行为
Docker 容器的标准输出(stdout)和标准错误(stderr)默认会被捕获并存储。
bash
# 查看容器日志
docker logs mycontainer
# 实时跟踪(类似 tail -f)
docker logs -f mycontainer
# 最后 100 行
docker logs --tail 100 mycontainer
# 带时间戳
docker logs -t mycontainer
# 查看 1 小时内的日志
docker logs --since 1h mycontainer应用日志最佳实践
容器内的应用应该将日志输出到 stdout/stderr,而不是写入文件:
javascript
// Node.js 示例
console.log('Info message'); // → stdout
console.error('Error message'); // → stderrpython
# Python 示例
import sys
print('Info message') # → stdout
print('Error message', file=sys.stderr) # → stderr如果应用只支持文件日志,可以将日志文件链接到 stdout:
dockerfile
# Nginx 官方镜像的做法
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log日志驱动
Docker 支持多种日志驱动,在 /etc/docker/daemon.json 中全局配置,或每个容器单独配置。
常用日志驱动
| 驱动 | 说明 |
|---|---|
json-file | 默认,将日志存储为 JSON 文件 |
local | 类似 json-file,但压缩存储,占用空间更小 |
syslog | 发送到 syslog 守护进程 |
journald | 发送到 systemd journal |
fluentd | 发送到 Fluentd |
gelf | 发送到 Graylog(GELF 格式) |
awslogs | 发送到 AWS CloudWatch |
none | 禁用日志 |
配置 json-file 日志(防止磁盘耗尽)
json
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}bash
# 单个容器配置
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx日志存储位置
bash
# 查看容器的日志文件路径
docker inspect mycontainer --format '{{.LogPath}}'
# /var/lib/docker/containers/<id>/<id>-json.log
# 直接读取日志文件
sudo cat /var/lib/docker/containers/<container-id>/<container-id>-json.log集中化日志收集
生产环境通常需要将多容器日志集中收集,推荐 EFK 或 Loki 方案。
方案一:EFK(Elasticsearch + Fluentd + Kibana)
yaml
# docker-compose.yml
services:
elasticsearch:
image: elasticsearch:8.12.0
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xms512m -Xmx512m
volumes:
- es-data:/usr/share/elasticsearch/data
fluentd:
build: ./fluentd
volumes:
- /var/lib/docker/containers:/fluentd/log/containers:ro
depends_on:
- elasticsearch
kibana:
image: kibana:8.12.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
volumes:
es-data:将 Docker 日志驱动改为 fluentd:
json
{
"log-driver": "fluentd",
"log-opts": {
"fluentd-address": "localhost:24224",
"tag": "docker.{{.Name}}"
}
}方案二:Loki + Grafana(更轻量,推荐)
yaml
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- loki-data:/loki
promtail:
image: grafana/promtail:latest
volumes:
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /var/log:/var/log:ro
- ./promtail-config.yml:/etc/promtail/config.yml:ro
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
volumes:
loki-data:
grafana-data:Docker Compose 日志配置
yaml
services:
api:
image: myapi
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
labels: "service_name"
labels:
service_name: api日志查看技巧
bash
# 搜索包含关键词的日志
docker logs mycontainer 2>&1 | grep "ERROR"
# 查看最近 5 分钟的日志
docker logs --since 5m mycontainer
# 查看指定时间段的日志
docker logs --since "2024-01-01T10:00:00" --until "2024-01-01T11:00:00" mycontainer
# 多服务日志对比(Compose)
docker compose logs -f api nginx
# 带颜色区分
docker compose logs --no-color api | grep ERROR总结
日志管理要点:
- 应用输出到 stdout/stderr,让 Docker 统一管理
- 配置日志轮转(
max-size+max-file),防止磁盘耗尽 - 生产环境集中收集:Loki/EFK 等方案
- 添加结构化日志:便于检索和分析
- 不在容器内写日志文件:除非挂载到卷