Docker默认捕获容器的标准输出(stdout)和标准错误(stderr),并存储为JSON格式的日志文件。
# 查看容器日志
docker logs mycontainer
# 实时查看日志(类似tail -f)
docker logs -f mycontainer
# 查看最后100行日志
docker logs --tail 100 mycontainer
# 显示时间戳
docker logs -t mycontainer
# 查看指定时间后的日志
docker logs --since 2024-01-01 mycontainer
docker logs --since 1h mycontainer
# 查看指定时间前的日志
docker logs --until 2024-01-01 mycontainer
# 组合使用
docker logs -f --tail 50 --since 10m mycontainer
Docker支持多种日志驱动,用于不同的日志收集场景:
# 运行容器时指定日志驱动
docker run -d \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
# 全局配置(/etc/docker/daemon.json)
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"labels": "production",
"env": "os,customer"
}
}
max-size:单个日志文件最大大小(如10m、100k)max-file:保留的日志文件数量compress:是否压缩旧日志文件# Docker Compose配置
version: '3.8'
services:
web:
image: nginx
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"
compress: "true"
app:
image: myapp
logging:
driver: "syslog"
options:
syslog-address: "tcp://192.168.1.100:514"
tag: "myapp"
# 发送日志到远程syslog服务器
docker run -d \
--log-driver syslog \
--log-opt syslog-address=tcp://192.168.1.100:514 \
--log-opt tag="myapp-{{.Name}}" \
nginx
# 使用UDP协议
docker run -d \
--log-driver syslog \
--log-opt syslog-address=udp://192.168.1.100:514 \
nginx
# 启动Fluentd容器
docker run -d \
--name fluentd \
-p 24224:24224 \
-v /data/fluentd:/fluentd/log \
fluent/fluentd
# 应用容器发送日志到Fluentd
docker run -d \
--log-driver fluentd \
--log-opt fluentd-address=localhost:24224 \
--log-opt tag="docker.{{.Name}}" \
nginx
version: '3.8'
services:
# Elasticsearch
elasticsearch:
image: elasticsearch:8.5.0
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
volumes:
- es-data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
# Logstash
logstash:
image: logstash:8.5.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
depends_on:
- elasticsearch
# Kibana
kibana:
image: kibana:8.5.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
# 应用容器
app:
image: myapp
logging:
driver: "gelf"
options:
gelf-address: "udp://logstash:12201"
tag: "myapp"
volumes:
es-data:
# 查看容器日志文件路径
docker inspect --format='{{.LogPath}}' mycontainer
# 直接查看日志文件
sudo cat $(docker inspect --format='{{.LogPath}}' mycontainer)
# 日志文件默认位置
# Linux: /var/lib/docker/containers//-json.log
# macOS: ~/Library/Containers/com.docker.docker/Data/vms/0/
# Python应用日志配置
import logging
import sys
# 配置日志输出到stdout
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler(sys.stdout)]
)
logger = logging.getLogger(__name__)
logger.info("Application started")
# Node.js应用
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
transports: [
new winston.transports.Console()
]
});
logger.info('Application started');
# 使用docker-compose查看多个容器日志
docker-compose logs
# 查看特定服务日志
docker-compose logs web
# 实时查看所有服务日志
docker-compose logs -f
# 查看最近的日志
docker-compose logs --tail=100
# 过滤日志
docker logs mycontainer 2>&1 | grep ERROR
docker logs mycontainer 2>&1 | grep -i "error\|warning"
# 使用Prometheus监控日志
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp
labels:
- "prometheus.io/scrape=true"
- "prometheus.io/port=8080"
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
alertmanager:
image: prom/alertmanager
ports:
- "9093:9093"
grafana:
image: grafana/grafana
ports:
- "3000:3000"
# 清理容器日志
truncate -s 0 $(docker inspect --format='{{.LogPath}}' mycontainer)
# 清理所有容器日志
docker ps -q | xargs -I {} sh -c 'truncate -s 0 $(docker inspect --format="{{.LogPath}}" {})'
# 设置日志轮转防止磁盘占满
docker run -d \
--log-opt max-size=50m \
--log-opt max-file=3 \
nginx
# 查看容器启动失败的日志
docker logs $(docker ps -lq)
# 导出日志到文件
docker logs mycontainer > container.log 2>&1
# 实时监控多个容器
docker logs -f container1 &
docker logs -f container2 &
# 使用jq解析JSON日志
docker logs mycontainer 2>&1 | jq '.'