136 lines
4.3 KiB
Bash
Executable File
136 lines
4.3 KiB
Bash
Executable File
#!/bin/bash
|
||
# ===================================================================
|
||
# Docker 容器日志 & 镜像 & 系统日志 自动清理脚本
|
||
# 功能:
|
||
# 1. 容器日志超过阈值时自动 truncate
|
||
# 2. 清理悬空 Docker 镜像 (<none>:<none>)
|
||
# 3. 清理旧版本 topfans/* 镜像(保留 latest 和 v1.0.7)
|
||
# 4. 清理 /var/log 系统日志
|
||
# 使用:./cleanup-logs.sh [容器日志阈值GB] [系统日志阈值GB]
|
||
# 示例:./cleanup-logs.sh 2 2
|
||
# Cron 建议:0 3 * * * /opt/topfans/docker/cleanup-logs.sh 2 2 >> /var/log/cleanup-logs.log 2>&1
|
||
# ===================================================================
|
||
|
||
CONTAINER_THRESHOLD=${1:-2}
|
||
SYSLOG_THRESHOLD=${2:-2}
|
||
|
||
echo "=========================================="
|
||
echo "日志清理脚本"
|
||
echo "容器日志阈值: ${CONTAINER_THRESHOLD}GB"
|
||
echo "系统日志阈值: ${SYSLOG_THRESHOLD}GB"
|
||
echo "=========================================="
|
||
|
||
# ========== 1. 清理 Docker 容器日志 ==========
|
||
echo ""
|
||
echo "=== 检查容器日志 ==="
|
||
|
||
total_container_log=0
|
||
cleared_containers=0
|
||
|
||
for container in $(docker ps -q); do
|
||
log_file=$(docker inspect --format="{{.LogPath}}" "$container" 2>/dev/null)
|
||
container_name=$(docker inspect --format="{{.Name}}" "$container" 2>/dev/null | sed "s/^\///")
|
||
|
||
if [ -f "$log_file" ]; then
|
||
size_bytes=$(stat -c%s "$log_file" 2>/dev/null || echo 0)
|
||
size_gb=$((size_bytes / 1024 / 1024 / 1024))
|
||
|
||
total_container_log=$((total_container_log + size_bytes))
|
||
|
||
if [ $size_gb -ge $CONTAINER_THRESHOLD ]; then
|
||
truncate -s 0 "$log_file" 2>/dev/null
|
||
echo " ✅ 已清理: $container_name (${size_gb}GB)"
|
||
cleared_containers=$((cleared_containers + 1))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
total_container_gb=$((total_container_log / 1024 / 1024 / 1024))
|
||
echo "容器日志总大小: ${total_container_gb}GB"
|
||
echo "已清理容器数: $cleared_containers"
|
||
|
||
# ========== 2. 清理悬空 Docker 镜像 ==========
|
||
echo ""
|
||
echo "=== 检查悬空镜像 ==="
|
||
|
||
dangling_before=$(docker images -f "dangling=true" -q | wc -l)
|
||
echo "悬空镜像数量: ${dangling_before}"
|
||
|
||
if [ "$dangling_before" -gt 0 ]; then
|
||
docker image prune -f > /dev/null 2>&1
|
||
echo " ✅ 已清理 ${dangling_before} 个悬空镜像"
|
||
else
|
||
echo " (无悬空镜像)"
|
||
fi
|
||
|
||
# ========== 3. 清理旧版本 topfans/* 镜像 ==========
|
||
echo ""
|
||
echo "=== 检查旧版本业务镜像 ==="
|
||
|
||
KEEP_TAGS="latest v1.0.7"
|
||
old_images=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "^topfans/" | grep -vE ":($(echo $KEEP_TAGS | tr " " "|"))$")
|
||
|
||
old_count=0
|
||
if [ -n "$old_images" ]; then
|
||
old_count=$(echo "$old_images" | grep -c "topfans/" 2>/dev/null || echo 0)
|
||
fi
|
||
if [ "$old_count" -gt 0 ]; then
|
||
echo " 发现 ${old_count} 个旧版本镜像:"
|
||
echo "$old_images" | sed "s/^/ /"
|
||
echo "$old_images" | xargs -r docker rmi > /dev/null 2>&1
|
||
echo " ✅ 已清理"
|
||
else
|
||
echo " (无旧版本镜像)"
|
||
fi
|
||
|
||
# ========== 4. 清理 /var/log 日志 ==========
|
||
echo ""
|
||
echo "=== 检查系统日志 ==="
|
||
|
||
total_syslog_size=0
|
||
cleared_logs=0
|
||
|
||
for logfile in $(find /var/log -type f -name "*.log" 2>/dev/null); do
|
||
if [ -f "$logfile" ]; then
|
||
size_bytes=$(stat -c%s "$logfile" 2>/dev/null || echo 0)
|
||
size_gb=$((size_bytes / 1024 / 1024 / 1024))
|
||
|
||
total_syslog_size=$((total_syslog_size + size_bytes))
|
||
|
||
if [ $size_gb -ge $SYSLOG_THRESHOLD ]; then
|
||
truncate -s 0 "$logfile" 2>/dev/null
|
||
echo " ✅ 已清理: $logfile (${size_gb}GB)"
|
||
cleared_logs=$((cleared_logs + 1))
|
||
fi
|
||
fi
|
||
done
|
||
|
||
for gzfile in $(find /var/log -type f -name "*.gz" 2>/dev/null | head -20); do
|
||
if [ -f "$gzfile" ]; then
|
||
rm -f "$gzfile" 2>/dev/null && echo " ✅ 已删: $gzfile"
|
||
fi
|
||
done
|
||
|
||
for oldlog in $(find /var/log -type f -name "*.log.[0-9]*" 2>/dev/null); do
|
||
rm -f "$oldlog" 2>/dev/null && echo " ✅ 已删: $oldlog"
|
||
done
|
||
|
||
if command -v journalctl > /dev/null 2>&1; then
|
||
journalctl --vacuum-time=3d > /dev/null 2>&1
|
||
echo " ✅ journal 已清理(保留最近 3 天)"
|
||
fi
|
||
|
||
total_syslog_gb=$((total_syslog_size / 1024 / 1024 / 1024))
|
||
echo "系统日志总大小: ${total_syslog_gb}GB"
|
||
echo "已清理日志数: $cleared_logs"
|
||
|
||
# ========== 5. 磁盘状态 ==========
|
||
echo ""
|
||
echo "=== 当前磁盘状态 ==="
|
||
df -h /
|
||
|
||
echo ""
|
||
echo "=========================================="
|
||
echo "清理完成"
|
||
echo "=========================================="
|