<返回目录     Powered by claude/xia兄

第11课: 日志管理

Docker日志基础

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"
  }
}
json-file日志选项:

日志轮转配置

# 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驱动

# 发送日志到远程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收集日志

# 启动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

ELK日志收集方案

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 '.'

最佳实践

实践练习

  1. 配置容器日志轮转,限制单个文件10MB,保留3个文件
  2. 使用docker logs实时查看容器日志
  3. 搭建ELK日志收集系统
  4. 配置应用输出结构化JSON日志
  5. 使用grep过滤和分析日志中的错误信息