Не все логи живут в /var/log. Самописные сервисы часто пишут сюда:
/opt/app/logs/
/srv/project/log/
/data/custom/*.log
Реализуем для них контролируемую ротацию на bash.
💚 Задача
архивировать логи старше N дней;
удалять архивы старше M дней;
не ломать активный файл;
не удалять то, что еще пишется.
1️⃣ Поиск логов старше N дней
LOG_DIR="/opt/app/logs"
DAYS=7
find "$LOG_DIR" -type f -name "*.log" -mtime +$DAYS
-mtime +7 - старше 7 дней.⚠️
mtime - это время последнего изменения.2️⃣ Архивирование с датой. Добавим gzip и текущую дату:
ARCHIVE_DIR="/opt/app/archive"
mkdir -p "$ARCHIVE_DIR"
find "$LOG_DIR" -type f -name "*.log" -mtime +7 -print0 |
while IFS= read -r -d '' file; do
base=$(basename "$file")
gzip -c "$file" > "$ARCHIVE_DIR/${base}_$(date +%F).gz" && rm -f "$file"
done
Здесь важно:
-print0 + read -d '' - безопасно для пробеловgzip -c - сначала создаем архив&& rm - удаляем только если архив созданНикаких
rm до успешного gzip.3️⃣ Защита от удаления активного лога. Если сервис продолжает писать в файл, удалять его напрямую нельзя. Проверка через lsof:
if lsof "$file" >/dev/null 2>&1; then
echo "Файл используется, пропускаем: $file"
continue
fi
Альтернатива: ротировать только логи, которые не менялись X часов:
-mmin +1440
4️⃣ Удаление старых архивов. Храним архивы 30 дней:
find "$ARCHIVE_DIR" -type f -name "*.gz" -mtime +30 -delete
Лучше сначала проверить:
find "$ARCHIVE_DIR" -type f -mtime +30 -print
Только потом добавлять
-delete.5️⃣ Безопасный вариант с flock (чтобы не запустить дважды)
(
flock -n 200 || exit 1
# код ротации здесь
) 200>/var/lock/custom-log-rotate.lock
Теперь крон не создаст гонку.
▪️ Пример запуска через cron
0 3 * * * /usr/local/bin/custom_rotate.sh
BashTex 📱 #bash #utils