topfans/docker/cleanup-logs.sh
2026-06-11 16:35:56 +08:00

136 lines
4.3 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 "=========================================="