#!/bin/bash # ============================================================================= # IGNY8 Log Rotation Script # ============================================================================= # Rotates and compresses old log files # Usage: ./log-rotate.sh # ============================================================================= set -e LOG_DIR="/data/logs" ARCHIVE_DIR="${LOG_DIR}/archive" RETENTION_DAYS=30 # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' NC='\033[0m' log() { echo -e "${BLUE}[$(date '+%H:%M:%S')]${NC} $1" } log_success() { echo -e "${GREEN}✅ $1${NC}" } echo "==========================================" echo "IGNY8 Log Rotation" echo "$(date '+%Y-%m-%d %H:%M:%S')" echo "==========================================" echo "" # Create archive directory mkdir -p "${ARCHIVE_DIR}" # Rotate function rotate_log() { local log_file="$1" local max_size="${2:-50M}" if [[ ! -f "${log_file}" ]]; then return fi local size=$(stat -f%z "${log_file}" 2>/dev/null || stat -c%s "${log_file}" 2>/dev/null || echo 0) local max_bytes=$((50 * 1024 * 1024)) # 50MB if [[ ${size} -gt ${max_bytes} ]]; then local basename=$(basename "${log_file}") local timestamp=$(date +%Y%m%d_%H%M%S) local archive_file="${ARCHIVE_DIR}/${basename}.${timestamp}.gz" log "Rotating ${log_file} ($(numfmt --to=iec ${size}))" gzip -c "${log_file}" > "${archive_file}" > "${log_file}" # Truncate original log_success "Archived to ${archive_file}" fi } # Rotate production logs log "Checking production logs..." for log_file in "${LOG_DIR}/production"/*.log; do [[ -f "${log_file}" ]] && rotate_log "${log_file}" done # Rotate staging logs log "Checking staging logs..." for log_file in "${LOG_DIR}/staging"/*.log; do [[ -f "${log_file}" ]] && rotate_log "${log_file}" done # Rotate Caddy logs log "Checking Caddy logs..." for log_file in "${LOG_DIR}/caddy"/*.log; do [[ -f "${log_file}" ]] && rotate_log "${log_file}" done # Clean up old archives log "Cleaning old archives (> ${RETENTION_DAYS} days)..." DELETED=$(find "${ARCHIVE_DIR}" -name "*.gz" -mtime +${RETENTION_DAYS} -delete -print | wc -l) if [[ ${DELETED} -gt 0 ]]; then log "Deleted ${DELETED} old archive files" fi # Docker container logs log "Pruning Docker container logs..." for container in igny8_backend igny8_frontend igny8_celery_worker igny8_celery_beat; do if docker ps -a --format '{{.Names}}' | grep -q "^${container}$"; then LOG_FILE=$(docker inspect --format='{{.LogPath}}' "${container}" 2>/dev/null || true) if [[ -n "${LOG_FILE}" ]] && [[ -f "${LOG_FILE}" ]]; then local size=$(stat -c%s "${LOG_FILE}" 2>/dev/null || echo 0) if [[ ${size} -gt $((100 * 1024 * 1024)) ]]; then # 100MB log "Truncating Docker log for ${container}" truncate -s 0 "${LOG_FILE}" fi fi fi done # Report disk usage echo "" echo "Log disk usage:" du -sh "${LOG_DIR}"/* 2>/dev/null || echo "No logs found" echo "" log_success "Log rotation complete" echo "=========================================="