Логи на сотне серверов: в чём проблема

Почему привычный grep по логам перестаёт работать, как только серверов становится больше одного.

Централизованное логирование — практика сбора логов со всех машин и сервисов в единое хранилище, где их можно искать, фильтровать и анализировать из одной точки.

Один сервер — это просто

Пока приложение крутится на одной машине, диагностика тривиальна. Случилась ошибка — заходишь по ssh, открываешь /var/log/app.log, делаешь grep ERROR и читаешь стектрейс. Логи лежат рядом, время на сервере одно, формат строки ты знаешь наизусть. Этот рабочий процесс настолько естественен, что кажется, будто он будет работать всегда.

ssh web-01
tail -f /var/log/app.log | grep -i error

Проблема в том, что этот подход линейно ломается с ростом инфраструктуры. И ломается он не плавно, а скачком — в тот момент, когда вы перестаёте помнить, на какой именно машине искать.

Сто серверов — это катастрофа

Представьте типичную современную систему: балансировщик раздаёт запросы на 20 инстансов веб-приложения, за ними 8 микросервисов в нескольких репликах каждый, очереди, воркеры, базы данных. Пользователь жалуется, что в 14:32 у него «всё зависло». Где искать?

Запрос прошёл через балансировщик (какой бэкенд он выбрал — неизвестно), попал на один из 20 веб-инстансов, тот сходил в три микросервиса, каждый из которых живёт в трёх репликах. Чтобы восстановить картину, нужно зайти на десятки машин, на каждой найти нужный файл, выбрать правильный диапазон времени и вручную сопоставить строки. К моменту, когда вы это сделаете, инцидент уже закончится — а если логи ротировались, нужные строки и вовсе исчезнут.

      Запрос пользователя (14:32)
            |
      [ Балансировщик ]  -- какой бэкенд?
       /    |     \
   web-03  web-11  web-17   -- 20 инстансов, лог на каждом
       |
   [ микросервис auth x3 ]  -- какая реплика ответила?
       |
   [ микросервис billing x3 ]
       |
   [ база данных ]

   Чтобы понять инцидент, надо собрать строки
   из ~7 разных файлов на ~7 разных машинах вручную.

Что именно ломается

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

  • Поиск не масштабируется. grep по одному файлу — мгновенно. grep по сотне машин — это скрипт с циклом по хостам, минуты ожидания и невозможность строить агрегаты («сколько всего ошибок за час по всем сервисам»).
  • Логи эфемерны. Контейнеры и поды в Kubernetes живут минуты. Под перезапустился — его файловая система исчезла вместе с логами. Расследовать инцидент по логам пода, которого уже нет, нельзя.
  • Ротация удаляет улики. logrotate сжимает и удаляет старые файлы, чтобы не забить диск. Нужная строка с прошлой недели может быть уже стёрта.
  • Нет корреляции. Логи разных сервисов в разных форматах, с разными часовыми поясами, без общего идентификатора запроса. Связать «ошибку в billing» с «таймаутом в auth» вручную почти нереально.
  • Нет доступа без прав. Чтобы дать аналитику или менеджеру возможность посмотреть логи, придётся раздавать ssh-доступ на прод — это недопустимо с точки зрения безопасности.

Как работает под капотом централизация

Идея проста: на каждом источнике стоит лёгкий агент, который читает логи и отправляет их по сети в единое хранилище. Хранилище индексирует данные так, чтобы по ним можно было искать полнотекстово и строить агрегаты за миллисекунды. Поверх — веб-интерфейс с поиском и графиками.

  [ источники логов ]      [ единое хранилище ]     [ UI ]
   web-01  ---agent--->
   web-02  ---agent---> --->  индекс по времени ---> поиск
   svc-A   ---agent--->        + полнотекст          графики
   k8s pod ---agent--->        + агрегаты            алерты

Ключевое отличие от «свалить все файлы в одну папку» — данные не просто хранятся, а индексируются. Поиск «все ошибки сервиса billing с кодом 500 за последний час» выполняется по инвертированному индексу, а не перебором строк. Именно это превращает мёртвый архив в инструмент расследования.

Что меняется в мышлении

Переход к централизованному логированию — это не только техническая, но и культурная перемена. Раньше лог был «личным дневником» одного сервера, который читал тот, кто на него зашёл. Теперь лог становится общим ресурсом команды: его пишут с расчётом, что читать будут другие люди и автоматика, через недели после события. Это меняет требования к самим логам — они должны быть самодостаточными (содержать достаточно контекста, чтобы понять запись без знания, на какой машине и в каком процессе она родилась) и единообразными по формату. Именно поэтому централизация почти всегда тянет за собой переход на структурированные логи и общие стандарты полей, о которых мы поговорим в отдельном разделе. Без этой дисциплины централизованное хранилище превращается в свалку строк, где формально всё собрано, но искать по-прежнему мучительно.

Ещё одно следствие — появляется единая шкала времени. На разрозненных серверах часы расходятся, часовые пояса разные, и сопоставить «что было раньше» трудно. Централизованная система требует синхронизации времени (NTP) и единого хранения времени в UTC, иначе хронология событий, собранных с разных машин, будет врать. Этот, казалось бы, мелкий пункт на практике критичен: разбор инцидента строится на точном порядке событий во времени.

Частые ошибки

  • «У нас же есть syslog». Классический rsyslog централизует, но не индексирует и почти не даёт аналитики. Это шаг в правильную сторону, но не решение для поиска и дашбордов.
  • Откладывать до первого крупного инцидента. Логирование надо ставить заранее: когда прод уже горит, разворачивать сбор логов поздно — нужных данных за прошлое всё равно не будет.
  • Логировать всё подряд без меры. Обратная крайность — слать в хранилище каждый DEBUG. Это дорого и зашумляет поиск. О балансе поговорим в разделах про объём и ILM.

Итоги

  • На одном сервере grep работает; на сотне — нет: поиск, корреляция и эфемерность логов становятся блокерами.
  • Централизованное логирование собирает логи со всех источников в единое индексированное хранилище.
  • Ключевая ценность — не хранение, а индексация: поиск и агрегаты за миллисекунды.
  • Ставить сбор логов нужно заранее, до инцидента, а не во время него.
Проверьте себя
1. Почему grep по SSH плохо масштабируется на распределённую систему?
AПотому что grep работает только с текстовыми файлами
BПотому что логи разбросаны по десяткам машин, эфемерны и не дают агрегатов по всем источникам сразу
CПотому что SSH медленный протокол
DПотому что grep не понимает регулярные выражения
2. Что является ключевым отличием централизованного хранилища логов от простого копирования файлов в одну папку?
AФайлы сжимаются для экономии места
BДанные индексируются, что даёт быстрый полнотекстовый поиск и агрегаты
CЛоги автоматически удаляются через сутки
DДоступ к папке защищён паролем
3. Почему логи в Kubernetes особенно требуют централизации?
AПоды живут недолго, и при перезапуске их файловая система с логами исчезает
BKubernetes вообще не пишет логи
CВ Kubernetes запрещён SSH
DЛоги в Kubernetes всегда в бинарном формате