Настройка log rotation и архивации логов сайта в 2026

Когда сайт начинает жить своей жизнью, логи разрастаются быстрее, чем люди успевают их читать. На моей практике уже через 2–4 недели без нормальной ротации access.log и error.log превращаются в свалку на десятки гигабайт, а иногда и в прямую причину падения диска на VPS с 20–30 ГБ SSD.

Я обычно настраиваю log rotation и архивацию сразу после запуска проекта, а не “когда-нибудь потом”. В 2026 году это уже не мелкая опция для зануд админов, а базовая гигиена сервера. Особенно если у вас WordPress, Битрикс или Laravel, где логи летят постоянно: от 404 и ботов до PHP-ошибок, cron-задач и интеграций с CRM.

Зачем вообще нужна ротация логов и архивация

Если говорить грубо, log rotation — это регулярная замена активного файла лога на новый с сохранением старого в архиве. Архивация — это уже следующий шаг: старые логи складываются в сжатом виде, подписываются по датам и живут отдельно от боевых файлов. И это однозначно стоит делать, потому что “один большой лог навсегда” — плохая идея.

Причин несколько. Первая и самая банальная — место на диске. Я видел серверы, где один только nginx/access.log раздувался до 18–25 ГБ за месяц, а вместе с PHP-FPM и логами CMS съедал весь свободный объём. Вторая причина — скорость анализа. Файл на 5–10 млн строк открыть можно, но смотреть его неприятно. Третья — безопасность и порядок. Старые логи надо хранить не бесконечно, а в понятной схеме, чтобы потом быстро поднять инцидент за нужную дату.

И ещё момент. Логи — это не только “что сломалось”. Это источник данных для аудита, расследования взлома, поиска ботов, анализа 500 ошибок и даже оптимизации. Если вы уже читали мою статью Настройка логов сайта: мониторинг и анализ ошибок в 2026, то логично продолжить именно отсюда: сначала привести логи в порядок, потом уже строить мониторинг.

ℹ️
Небольшая ремарка: для сайта на PHP 8.1/8.2/8.3 и MySQL 5.7/8.0 логов обычно больше, чем кажется. Плагин к плагину, cron к cron — и через месяц у вас не “немного ошибок”, а полноценный архив событий.

Какие логи стоит ротировать в первую очередь

На практике я начинаю не со всех файлов подряд, а с тех, которые реально растут. У Nginx это обычно access.log и error.log. У Apache — аналогично. У PHP-FPM — пуловые логи и журнал медленных запросов, если он включён. У Битрикса — свои системные и рабочие логи, если проект пишет их в файл. У WordPress часто логи живут через WP_DEBUG_LOG или в логах плагинов.

Если проект на Laravel, смотрим в storage/logs/laravel.log. И вот здесь я часто вижу одну и ту же ошибку: лог приложения не ротируется вообще. Он растёт в один файл месяцами, а потом разработчик удивляется, почему tail тормозит, а деплой начинает вести себя странно. На деле всё просто: файл стал огромным, и система упирается в ввод-вывод.

Ещё есть специфические логи: fail2ban, nginx rate limiting, cron, mail-лог, logs от CDN-агентов, от очередей задач. Если у вас настроен мониторинг, как в статье Как настроить мониторинг сайта: полное руководство, то ротация — это обязательный кусок инфраструктуры. Без неё алерты и разбор инцидентов становятся мучением.

💡
Совет: сначала составьте список всех файлов логов на сервере: find /var/log -type f, плюс логи приложений в проектах. Я обычно делаю это на свежем сервере сразу после установки Nginx 1.24/1.26, PHP 8.2 и MySQL 8.0, чтобы не пропустить “мусорные” журналы от сервисов.

Logrotate на Linux: базовая схема работы

В 2026 году основной инструмент на большинстве Linux-серверов — это всё тот же logrotate. Да, штука старая. Но она по-прежнему работает стабильно и предсказуемо. Для сайтов на Ubuntu 22.04/24.04, Debian 12/13, AlmaLinux 9 и Rocky Linux 9 это стандарт де-факто.

Логика простая: раз в день или раз в неделю cron запускает logrotate, тот проверяет конфиги в /etc/logrotate.conf и /etc/logrotate.d/, архивирует старые файлы, создаёт новые, сжимает, удаляет старьё по сроку хранения. И именно здесь важно правильно задать права, владельца, частоту и количество копий.

Был у меня клиент на Bitrix, где ротация была настроена “на глаз”: каждый день создавался новый файл, но старые не удалялись. В итоге через 3 месяца папка /var/log/nginx заняла почти 40 ГБ. Сервер не упал только потому, что диск был 80 ГБ, но это был уже не сервер, а ходячая проблема.

Пример настройки для Nginx

Вот рабочий пример для Nginx. Я обычно кладу такие настройки в /etc/logrotate.d/nginx или отдельный файл для конкретного сайта, если проект большой.

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        systemctl reload nginx > /dev/null 2>&1 || true
    endscript
}

Что здесь важно. rotate 14 хранит 14 архивов, то есть примерно две недели при ежедневной ротации. compress включает сжатие, обычно через gzip. delaycompress оставляет самый свежий архив несжатым до следующего цикла — это удобно, если какой-то процесс ещё держит дескриптор файла. create задаёт права нового лога. И postrotate перезагружает Nginx, чтобы он начал писать в новый файл.

Но вот тут есть нюанс. Если у вас сайт под высокой нагрузкой, не всегда нужен reload каждый раз. Иногда лучше использовать copytruncate, но я это делаю только в крайних случаях. Честно говоря, это компромисс с риском потерять несколько строк логов при копировании. Для критичных систем я больше люблю нормальный postrotate с reload.

⚠️
Не делайте так: не ставьте copytruncate “на всякий случай” везде подряд. Для Nginx, PHP-FPM и Laravel это иногда терпимо, но на боевых проектах я предпочитаю ротацию через корректный reload или restart сервиса. Иначе можно получить потерянные строки именно в момент ошибки.

Архивация логов: сжатие, сроки хранения и структура папок

Ротация сама по себе решает только часть задачи. Архивация нужна для того, чтобы старые логи не лежали в виде простыни из десятков файлов без структуры. Я обычно рекомендую хранить архивы по схеме, которую легко читать глазами: по сервису, по году, по месяцу, иногда по домену.

Например, на проектах с несколькими сайтами удобно складывать логи так:

/var/log/sites/example.com/nginx/
 /var/log/sites/example.com/php-fpm/
 /var/log/sites/example.com/app/
 /var/log/sites/example.com/archived/

Или ещё лучше — отдельный каталог под каждый виртуальный хост. Это особенно помогает, если вы обслуживаете мультисайтовую инфраструктуру, как в статье Настройка мультидоменного сайта: полное руководство 2026. Там без порядка в логах вообще делать нечего.

По сжатию я чаще использую gzip, потому что это стабильно, быстро и понятно для любой команды. xz даёт сильнее сжатие, но на практике он медленнее, и для ежедневных логов сайта это редко оправдано. Если архивов много и хранить их нужно 6–12 месяцев, то gzip обычно достаточно. На VPS с 2 vCPU и 2 ГБ RAM я не советую городить сложные схемы с тяжёлым сжатием: выгода небольшая, а нагрузка растёт.

Срок хранения тоже надо считать здраво. Для магазина на 10–20 тысяч визитов в день я часто ставлю 30 дней горячего хранения и 90–180 дней холодного. Для небольшого корпоративного сайта достаточно 14–30 дней активных логов и архивов на 2–3 месяца, если нет требований комплаенса. Для проектов с безопасностью, платежами и большим трафиком сроки могут быть другими. Тут уже смотрим не “как красиво”, а “что реально нужно бизнесу”.

Настройка для WordPress, Битрикс и Laravel

На WordPress логика обычно проще всего. Если включён WP_DEBUG_LOG, лог пишется в файл wp-content/debug.log. И вот его обязательно надо ротировать, потому что при активных плагинах он улетает в рост очень быстро. Особенно если есть ошибки от темы, кривой плагин кэша или интеграция с платежкой.

У Битрикса история сложнее. Там бывает несколько источников логов: агентские задачи, события, интеграции, отладка модулей, журнал ошибок. Если проект активно дорабатывается, я почти всегда отдельно вывожу логи приложения и отдельно — логи веб-сервера. Это облегчает поиск причин, особенно когда у вас PHP 8.2 и старый модуль, который любит писать предупреждения на каждый чих. Если нужно навести порядок глубже, я бы ещё посмотрел статью Настройка кеширования в Битрикс: полное руководство — там логика оптимизации тесно связана с тем, что именно пишется в логи при ошибках кеша.

Laravel — отдельная песня. У него есть нормальный канал логирования, но если оставить всё по умолчанию, single-лог будет расти без ротации. Я чаще перевожу проекты на daily и ставлю лимит, например 14 или 30 дней. Это и удобно, и безопасно.

Пример для Laravel

'channels' => [
    'daily' => [
        'driver' => 'daily',
        'path' => storage_path('logs/laravel.log'),
        'level' => env('LOG_LEVEL', 'debug'),
        'days' => 14,
    ],
],

На деле это один из самых простых способов убрать ручную возню. Но если проект старый, там часто стоит single и файл laravel.log улетает в гигабайты. Тогда я меняю конфиг, очищаю старый лог и перезапускаю очередь, если она есть. Для проектов с очередями и cron это особенно важно, и тут хорошо работает связка с темой из статьи Настройка cron jobs: автоматические задачи на сайте в 2026.

ℹ️
Практика: для WordPress и Laravel я часто ставлю ротацию на 7–14 дней, а для Битрикса — 14–30 дней, если проект активно дорабатывается. На стабилизированном сайте можно хранить дольше, но только если у вас есть место и понятная политика хранения.

Автоматизация через cron и собственные скрипты

Если стандартного logrotate мало, можно добавить свои скрипты. Я это делаю, когда нужно не просто ротировать, а ещё и складывать архивы в отдельное хранилище, отправлять их в S3, на NAS или в другой сервер. В 2026 году это уже обычная история, особенно если проект живёт в Docker или на нескольких инстансах.

Например, можно раз в ночь собирать архивы за сутки, подписывать их датой и выгружать через rclone или aws cli. Это полезно, если вы хотите хранить логи отдельно от продакшн-сервера. И это хорошая идея, потому что при взломе или падении VPS локальные логи тоже можно потерять.

Вот пример простого shell-скрипта для упаковки логов Nginx:

#!/usr/bin/env bash
set -euo pipefail

LOG_DIR="/var/log/nginx"
ARCHIVE_DIR="/var/log/archive/nginx"
DATE="$(date +%F)"

mkdir -p "$ARCHIVE_DIR"

find "$LOG_DIR" -maxdepth 1 -type f -name "*.log" -mtime +0 | while read -r file; do
    base="$(basename "$file")"
    gzip -c "$file" > "$ARCHIVE_DIR/${base}.${DATE}.gz"
    : > "$file"
done

Но я сразу скажу: в чистом виде такой подход годится не всегда. Если файл активно пишется, обнулять его через : опасно. Поэтому для боевого проекта лучше использовать либо logrotate, либо аккуратную ротацию через сервисный reload. Этот скрипт — скорее иллюстрация принципа.

Если хотите автоматизировать больше процессов на сайте, у меня есть отдельная статья Автоматическое обновление контента: настройка и инструменты. Там логика похожая: всё, что можно увести в планировщик, лучше увести. Но только с контролем и логированием самих задач.

Контроль ошибок, персональные данные и безопасность архивов

С логами есть неприятный момент: в них часто попадает слишком много лишнего. IP-адреса, токены, куски POST-запросов, email, иногда даже персональные данные, если приложение написано неаккуратно. Поэтому хранить логи надо не просто “как есть”, а с пониманием рисков. Это уже не чисто техническая тема, а вопрос безопасности.

Я обычно проверяю, не пишутся ли в логи cookie, Authorization header, ключи API и содержимое форм. Если пишутся — это надо исправлять сразу. Иначе вы складываете в архив то, что хранить вообще нельзя. Для этого полезно свериться с подходами из статьи Защита API-ключей на сайте: настройка и хранение 2026. Логи и секреты рядом быть не должны.

По правам доступа тоже всё просто: логи должен читать только тот, кому они нужны. Не надо делать chmod 777 и не надо раздавать доступ всем подряд. На Nginx я обычно ставлю 0640 и группу adm или отдельную сервисную группу. Архивы можно складывать в каталог с более жёсткими правами и, если нужно, шифровать на уровне хранилища.

⚠️
Осторожно с архивами: если в логах есть чувствительные данные, срок хранения надо сокращать. А в некоторых проектах старые логи лучше вообще удалять через 14–30 дней, не выгружая их в облако без шифрования.

Что проверить после настройки

После того как вы настроили ротацию, не надо считать работу завершённой. Я всегда делаю короткий чек после внедрения. Смотрю, создаются ли новые файлы, сжимаются ли старые, не растут ли логи без остановки, не падает ли сервис после reload. На больших проектах я ещё проверяю, не ломается ли сбор логов в мониторинге.

Практически всегда я тестирую вручную. Команда logrotate -d показывает, что будет сделано, без реального выполнения. logrotate -f принудительно запускает ротацию. После этого я смотрю размеры файлов, дату изменения и наличие архивов. Если что-то не так — правлю сразу, а не через неделю, когда диск уже красный.

Полезно проверить и смежные вещи. Например, если у вас уже настроен сервисный мониторинг из статьи Настройка uptime-мониторинга сайта в 2026 году, то можно добавить контроль наличия новых логов и отсутствие аномального роста. А если проект часто падает с 500-ошибками, обязательно сопоставьте логи с материалом Ошибка 500 на сайте: причины и решения — это помогает быстро отличить проблему приложения от проблемы сервера.

Мини-чеклист после внедрения

Ошибки, которые я видел на практике

Самая частая ошибка — полное отсутствие ротации. Потом идут полурабочие схемы, где логи архивируются, но не сжимаются, или сжимаются, но не удаляются. Ещё одна типичная проблема — дублирование. Например, logrotate уже всё делает, а сверху разработчик пишет свой cron, который ещё раз архивирует те же файлы. В итоге появляются странные копии и путаница по датам.

Был случай с интернет-магазином на WordPress + WooCommerce. Сайт работал на PHP 8.1, Nginx и MariaDB 10.6. После обновления плагина начали сыпаться предупреждения, debug.log рос по 300–500 МБ в сутки, а ротации не было. Через 11 дней диск на 100 ГБ забился полностью, и сайт начал отдавать 500 ошибки. Проблема решилась не “починкой диска”, а нормальной ротацией, отключением мусорного debug-режима и переносом архивов в отдельное хранилище.

Другой клиент — B2B-проект на Laravel — хранил все логи приложения в одном файле и ещё отправлял его в ELK. На первый взгляд удобно, но на деле без ротации локальный файл всё равно раздувался. После перехода на daily и хранения 14 дней мы не только убрали лишнюю нагрузку, но и ускорили разбор ошибок. На медленных серверах это чувствуется сразу, особенно если рядом ещё крутится Redis и очередь задач. Кстати, про ускорение можно посмотреть Настройка Redis для сайта: ускорение WordPress, Bitrix и Laravel.

Что я рекомендую делать в 2026 году

Если коротко, я бы не усложнял без нужды. Для 80% сайтов хватает связки: logrotate, сжатие gzip, хранение 14–30 дней, отдельный каталог для архивов и нормальный контроль прав доступа. Для WordPress и Laravel можно добавить ротацию на уровне приложения. Для Битрикса и Nginx — держать системные логи отдельно и не мешать их с логами проекта.

Если сайт уже живёт на проде, обязательно проверьте, как ротация сочетается с бэкапами. Иначе можно случайно бэкапить и активные, и архивные логи, раздувая резервные копии в два раза. Это плохая идея. В статье Бэкапы сайта: как делать правильно и не терять данные я уже писал, что лишний мусор в резервных копиях потом дорого обходится.

Если у вас всё это ещё не настроено, я бы начал с простого аудита: какие логи есть, сколько весят, кто их пишет, где они лежат, сколько дней хранить и нужны ли они вообще в архиве. После этого ротация и архивация настраиваются за 20–40 минут на типовом сервере. И это одна из тех задач, которые один раз делают инфраструктуру заметно спокойнее.

Если нужна аккуратная настройка log rotation, архивации логов, прав доступа, cron-задач и связки с мониторингом — я обычно беру такие задачи в рамках доработки сайта и поддержки Битрикс, а для WordPress у меня есть отдельная поддержка WordPress. На практике это дешевле, чем потом разбирать упавший диск, потерянные логи и непонятную 500-ошибку в пятницу вечером.

Нужна помощь с настройкой log rotation?

Поможем настроить ротацию и архивацию логов сайта так, чтобы данные хранились безопасно, а сервер не переполнялся.

П
Павел
Веб-разработчик · 10+ лет опыта · Bitrix, WordPress, Laravel

Читайте также

Настройка HTTP/2 и HTTP/3 для ускорения сайта в 2026 Как настроить автопродление SSL-сертификата в 2026 Переход на HTTPS: полный чек-лист