RE:NODE

Эксплуатация14 мин чтения

Логи сервера, которые стоит хранить: что и как долго

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

Обновлено

0 прочтений

Храните всё уровня warning и выше, каждый стартовый баннер, каждый crash report целиком и каждое административное действие. Access-логи по каждому запросу удаляйте через неделю-две, отладочный вывод - в день закрытия бага, и перестаньте писать всё, что печатается на каждом тике. Вот и вся политика, и она умещается в четыре строки, потому что трудно не решить, что хранить, а сделать так, чтобы решение пережило встречу с сервером, у которого есть лимит диска, нет сервера логов и есть привычка выдавать по 500 MB болтовни в день, которую никто никогда не прочтёт.

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

Для чего на самом деле нужны логи#

Лог - это запись, которую читают в обратном порядке от момента, когда что-то сломалось. На практике ему нужно отвечать всего на четыре вопроса, и любая строка, которая не помогает ни с одним из них, - украшение:

  • Что работало? Какая версия, какая Java, какие моды и плагины каких версий, какой файл конфигурации прочитан, какие порты заняты.
  • Что изменилось и когда? Обновили плагин, отредактировали конфигурацию, кто-то перезапустил с другими флагами.
  • Что процесс сказал перед смертью? Последние несколько сотен строк и стек вызовов, по порядку, с временными метками.
  • Кто что сделал? Баны, кики, выдача прав, создание предметов, правки мира, деплои.

Обратите внимание: три из четырёх вопросов - про время. Ценность лога почти целиком в порядке событий и временных метках, а не в формулировках сообщений. Лог с красивой прозой и без временных меток почти бесполезен; лог из скупого машинного вывода с точными метками скажет вам, что произошло. Поэтому на вопрос «вчера вечером сервер тормозил» ответить можно, а на «в последнее время сервер тормозит» - обычно нет.

Храните эти четыре вещи#

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

Вывод при запуске целиком. Это самый недооценённый блок в любом файле лога. В нём записаны точная версия серверного ПО, версия Java или среды выполнения, полный список реально загруженных модов или плагинов с номерами версий, открытые мир или база данных и занятые порты. Когда вам говорят, что ничего не менялось, стартовый баннер «до» и «после» позволяет доказать обратное за тридцать секунд. На сервере Minecraft это блок от Starting minecraft server version до Done (12.481s)! For help, type "help". На сервере с модами это список модов. Храните его, даже когда остальную часть дня выбрасываете.

Crash reports целиком, в том числе те, которые вам кажутся понятными. Стек вызовов, обрезанный до «интересного места», - это стек вызовов, из которого интересное место убрали. Minecraft пишет их в crash-reports/crash-<date>-server.txt, а также в консоль. JVM, которая падает на уровне нативного кода, пишет hs_err_pid<pid>.log в рабочий каталог - это файл, который скажет, что вас убил OOM killer ядра, а не ваш код. Эти файлы маленькие. Нет такого варианта, в котором их удаление было бы верным решением.

Административные действия. Баны, кики, смена прав, правки цен, выдача предметов, деплои конфигурации. Эти действия оспаривают, причём через недели и человек со скриншотом. Храните их дольше всего остального и там, где проверяемый не сможет их отредактировать.

Удаляйте это, а кое-что перестаньте писать#

Access-логи по каждому запросу старше недели-двух. Они отвечают на вопросы о трафике, а это настоящие вопросы, но двух недель хватает на все, которые вы реально зададите, а сами эти логи обычно занимают на порядок больше места, чем любой другой файл на диске.

Отладочный вывод, оставленный включённым после окончания отладки. Это самая частая причина каталога логов, который незаметно съел тариф. Отладочное логирование - инструмент, который берут в руки и откладывают, а не настройка.

Всё, что печатается на каждом тике. Эта последняя категория - не логирование, а проблема производительности, которая просто пишет в файл. При 20 тиках в секунду одна строка на тик - это 1,7 миллиона строк в сутки, а запись обычно идёт в том же потоке, что и симуляция, так что цена ложится прямо на бюджет тика. Если так делает плагин, исправлять надо конфигурацию плагина, а не увеличивать диск. Как найти виновника, описано в статье почему падает TPS и что с этим делать.

Логи чата и IP-адреса заслуживают отдельного, неудобного абзаца. И то и другое в большинстве стран - персональные данные, и то и другое действительно полезно для модерации, а хранение любого из них вечно превращает инструмент модерации в обязательство, которое вы храните за людей, не просивших об этом. Тридцати-девяноста дней чата хватит, чтобы закрыть любой спор, который ещё стоит закрывать. Недавние версии ванильного сервера Minecraft добавили именно по этой причине переключатель log-ips в server.properties; проверьте, есть ли он в вашей версии, прежде чем считать, что адреса пишутся.

Как долго что хранить#

Срок хранения - это бюджет, а не принцип. Вот разбивка, которая работает на одном сервере с обычным объёмом диска:

ЛогХранитьПримечания
Crash reports и стеки вызововБессрочноПо несколько килобайт. Скопируйте их с сервера
Стартовые баннеры90 днейИзвлекайте их, если полный лог слишком велик
Предупреждения и ошибки30-90 днейПолезная середина всего файла
Административные действия и модерация6-12 месяцевВне сервера, лучше в базе данных
Чат30 днейПерсональные данные. Чем короче, тем безопаснее
Access-логи7-14 днейВ сжатом виде. Самый большой файл из всех
Отладочный выводДо закрытия тикетаПотом выключить, а не просто ротировать

Правило, стоящее за таблицей: храните лог столько, сколько кто-то может разумно прийти к вам с вопросом об этом периоде. Для падений это навсегда, потому что то же падение возвращается. Для access-логов - примерно столько, сколько живёт последний счёт.

Ротация, сжатие и тот диск, который у вас есть#

Один раз посчитайте, потому что результат неинтуитивен. Типичная строка лога - около 120 байт. Сервер, пишущий 50 строк в секунду, - вполне обычный загруженный сервер Minecraft или веб-сервер - выдаёт около 6 KB/s, то есть примерно 500 MB в сутки или 15 GB в месяц. На тарифе с 15 GB это весь диск за тридцать дней, и проявится сбой не как проблема с логами. Он проявится как сохранение мира, которое не удалось, ошибка записи в базу данных или бэкап, который не завершается.

Текстовые логи сжимаются примерно в десять раз, так что сжатие при ротации - почти бесплатные 90 процентов. В Linux стандартный инструмент - logrotate, и конфигурация для приложения, которое пишет собственные файлы, выглядит так:

/etc/logrotate.d/myapp
/home/app/logs/*.log {    daily    rotate 14    compress    delaycompress    missingok    notifempty    copytruncate}

copytruncate копирует файл, а затем очищает оригинал на месте, и именно это нужно процессу, который держит файл открытым и не умеет переоткрывать его по команде. Ценой становится крошечное окно, в котором строки, записанные во время копирования, теряются. Альтернатива - create с блоком postrotate, который посылает процессу сигнал переоткрыть лог, - чище, если ПО это поддерживает. Большинство игровых серверов не поддерживает, поэтому copytruncate обычно и есть честный выбор.

Если служба работает под systemd и пишет в stdout, ротацию уже делает журнал, и файл на диске вам не принадлежит. Ограничьте журнал в /etc/systemd/journald.conf:

/etc/systemd/journald.conf
Storage=persistentSystemMaxUse=500MSystemMaxFileSize=50MMaxRetentionSec=1month

Игровые серверы ведут себя каждый немного по-своему, и одно поведение раз за разом застаёт людей врасплох. Minecraft и его форки ротируют логи при запуске, а не по таймеру: текущий файл - logs/latest.log, а предыдущий сжимается в logs/2026-09-20-1.log.gz при следующем запуске сервера. Сервер, проработавший шесть недель без перезапуска, имеет один-единственный latest.log, который всё это время растёт, и до перезапуска его никто не ротирует. Это ещё один небольшой довод в пользу еженедельного перезапуска из статьи расписания перезапуска, которые помогают.

Project Zomboid идёт в обратную сторону и при каждом запуске пишет в Logs/ новый набор файлов с датой, разбитый по видам: _DebugLog-server.txt, _chat.txt, _admin.txt, _user.txt, _pvp.txt, _map.txt, _item.txt. Для поиска это превосходно, а для диска ужасно, потому что никто и никогда их не чистит. Повесьте на эту папку задачу по расписанию, иначе она переживёт мир.

Снижаем шум у источника#

Ротация лечит симптом. Настоящая победа - не писать строку вообще.

В nginx шум почти всегда составляют успешные запросы, а сигнал - ошибки. Можно логировать только интересные:

nginx
map $status $loggable {    ~^[23]  0;    default 1;}access_log /var/log/nginx/access.log combined if=$loggable;error_log  /var/log/nginx/error.log warn;

Так сохраняются все 4xx и 5xx, а остальное отбрасывается, и на загруженном сайте это 95 процентов объёма. Задайте error_log уровня warn и оставьте так; debug в nginx требует сборки с модулем отладки и заполнит диск быстрее всего остального в этой статье.

В приложении на Node используйте логгер с уровнями вроде pino вместо console.log, управляйте уровнем через переменную окружения и никогда по умолчанию не логируйте тела запросов. В Python хватает стандартной библиотеки, а самая действенная строка - заглушить библиотеку, которая думает, что вам интересен её вывод:

python
import logginglogging.basicConfig(level=logging.INFO)logging.getLogger("urllib3").setLevel(logging.WARNING)logging.getLogger("botocore").setLevel(logging.WARNING)

На игровом сервере на Java логгер - Log4j2, а уровень задаётся файлом конфигурации, на который JVM указали через -Dlog4j.configurationFile=. Менять его можно, но это хлопотно, и на практике шум на сервере Minecraft исходит от одного-двух плагинов с debug: true в их собственной конфигурации. Найдите их в первую очередь. По-настоящему тревожная строка, Can't keep up! Is the server overloaded? Running 2154ms or 43 ticks behind, шумом не является, как бы часто ни появлялась: так сервер сообщает, что пропустил две секунды симуляции.

В панели консоль и есть лог. Консоль RE:NODE показывает нефильтрованный вывод в реальном времени, с командной строкой, у которой есть история и автодополнение по Tab, и сворачивает повторяющийся шум запросов веб-сервера за счётчик, который можно отключить, - та же идея, что и map в nginx выше, только применённая в точке чтения. О том, что означают частые строки, рассказано в статье как читать консоль.

Как найти нужную строку#

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

bash
$ grep -n -C 3 -iE "error|exception|warn" logs/latest.log | less$ zgrep -h "Exception" logs/*.log.gz | sort | uniq -c | sort -rn | head -20$ journalctl -u myapp -p warning --since "2026-09-20 18:00" --until "2026-09-20 19:30"

Вторую строку стоит выучить наизусть. Она читает все ротированные логи, вытаскивает исключения и показывает, сколько раз встретилось каждое из них, начиная с самых частых. В девяти случаях из десяти ответ на вопрос «что не так с этим сервером» - верхняя строка этого вывода.

Прежде чем доверять чему-либо из этого, выясните две вещи. Первая - в каком часовом поясе лог: контейнеры обычно работают в UTC, панель может показывать местное время, и смещение в час заставит вас читать совсем не то окно. Вторая - читайте с начала. В стеке вызовов первая строка, называющая что-то, что не является игрой или фреймворком, - ваш подозреваемый; последняя строка - обычно общий обработчик, который это поймал. Одна эта привычка - почти всё содержание статьи что делать, когда обновление мода всё ломает.

Действия администраторов и логи, которые оспаривают#

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

В большинстве игр есть специально созданный ответ. Project Zomboid пишет _admin.txt и _pvp.txt, как описано выше. В Minecraft CoreProtect записывает изменения блоков и контейнеров в собственную базу данных и через недели отвечает на запросы /co lookup и /co rollback, а LuckPerms ведёт свой журнал действий по каждому изменению прав, доступный через /lp log recent. Серверы FiveM с txAdmin получают журнал команд администраторов, привязанный к именованным аккаунтам, а не к тому, кто оказался в консоли.

Уровень панели здесь тоже важен. Если все, кто администрирует сервер, пользуются одним логином, никакой лог в мире не скажет вам, кто это сделал. Заведите каждому человеку отдельный аккаунт с нужными ему правами - в RE:NODE это субпользователи, роли и команды с гранулярными правами и журнал активности для каждого сервера; как разделять права, разобрано в статье субпользователи и принцип наименьших привилегий. То же относится к удалённому доступу к консоли: в статье безопасная работа с RCON объясняется, почему открытый порт RCON делает ненадёжными все остальные логи в этой статье: любой может выполнить команду от имени никого.

Как вынести логи с машины#

Лог, существующий только на сгоревшем сервере, - не доказательство, а надежда. Для этого не нужен стек логирования. В порядке возрастания усилий:

  1. Скачивайте интересные файлы вручную после любого инцидента, пока ничего не ротировано. Пять минут, настройка не нужна, и это полностью закрывает случай с crash report.
  2. Задача по расписанию, которая сжимает вчерашние логи и кладёт архив туда, откуда вы сможете его забрать. Cron-выражение, консольная команда и файл, который вы забираете по SFTP - схемы есть в статье задачи по расписанию, которые стоит завести.
  3. Webhook только для предупреждений. Не поток логов, а фильтр, который отправляет ошибки в канал. Условие в том, что он должен молчать настолько, чтобы люди всё ещё его читали. Об этом компромиссе целиком статья мониторинг, который что-то вам говорит.
  4. База данных для административных действий и модерации - единственной категории, для которой структура оправдана. Слота игровой базы данных или небольшого управляемого экземпляра вполне достаточно.

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

И последнее, о чём логи не могут рассказать сами: сервер, который перезапускается снова и снова, ротирует улики того, почему это происходит. RE:NODE за этим следит - каждые две минуты проверяет, не пошёл ли аптайм назад, а три неожиданных перезапуска за час поднимают предупреждение на странице сервера и автоматически открывают тикет, - но окно лога, которое вам нужно, - то, что было непосредственно перед первым перезапуском, а не перед последним. Заберите его пораньше. Об обычных причинах рассказано в статье почему игровой сервер постоянно перезапускается.

FAQ#

Как долго хранить логи сервера?

Crash reports - бессрочно, предупреждения и ошибки - от 30 до 90 дней, действия администраторов - от шести до двенадцати месяцев, access-логи - одну-две недели, чат - около тридцати дней. Если запоминать одно число, пусть будет четырнадцать дней для объёмного и навсегда для маленького.

Замедляет ли логирование сервер?

Обычное - нет. Отладочное на загруженном сервере - да, измеримо, потому что запись часто идёт в потоке, который выполняет работу, и потому что она конкурирует за тот же диск, что и ваши сохранения. Строка лога, печатаемая на каждом тике, - это ошибка производительности, куда бы её ни писали.

Достаточно ли мне одного latest.log?

Нет. latest.log охватывает только текущий запуск, а на сервере Minecraft он не ротируется до следующего старта, так что может быть одновременно огромным и неполным. Ротированные файлы .log.gz рядом хранят предыдущие запуски, а crash-reports/ - то, что было слишком плохо, чтобы нормально попасть в лог.

Можно ли просто хранить всё вечно?

Crash reports и стартовые баннеры можно хранить вечно, потому что они крошечные. Хранение сырых access-логов, чата и IP-адресов вечно стоит реального места на диске, замедляет поиск и означает, что вы храните чужие персональные данные без всякого плана. Сохраняйте мелкое, а крупное ротируйте.

Что приложить к обращению в поддержку?

Полный лог от последнего чистого запуска до сбоя, crash report, если он есть, и то, что вы меняли в последнюю очередь. Не скриншот консоли и не последние двадцать строк: последние двадцать строк почти всегда - уборка, а не причина. В тикет панели можно прикладывать приватные вложения, так что весь файл приложить можно.

Диск заполнился за ночь. С чего начать?

Отсортируйте каталог сервера по размеру и ожидайте, что ответом окажется папка логов, папка crash reports либо собственный каталог данных какого-нибудь плагина. Сначала удалите ротированные архивы, потом исправьте настройку, которая породила объём, и только после этого решайте, не мал ли тариф на самом деле.


Комментарии

Полностью анонимно: без аккаунта, без почты, без cookie. Мы храним имя, которое вы ввели, текст и время - больше ничего. Количество ссылок ограничено, разметка не отображается.

0/2000