Коротко. Собирайте журналы сервисов, прокси, базы, брокера, хостов и событий безопасности, разбирайте на поля и приводите время к одной зоне. Предел, о который всё останавливается, находится не на диске: в Elasticsearch это число шардов, в Splunk суточный объём приёма. Посчитайте его заранее, а не в день инцидента.

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

Симптом

Инцидент разбирается вручную. Администратор подключается к каждому серверу по очереди, ищет по времени, сопоставляет записи глазами. На один случай уходит несколько часов, и половина ответов звучит как «похоже, было так».

Сопутствующие признаки: на вопрос «кто и когда менял права на папку» ответа нет; после перезапуска сервиса причина перезапуска неизвестна; при обращении к вендору в тикет попадает пересказ, а не выдержка из журнала, и переписка растягивается на недели.

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

Почему так

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

Три причины, по которым ручной разбор не масштабируется:

  • Время. На одной машине время в местной зоне, на другой в UTC, у третьей ушли часы. Сопоставление событий по времени становится гаданием. Поэтому синхронизацию времени проверяют в контуре первой.
  • Ротация. Файлы обрезаются по размеру или по дате. Инцидент недельной давности разбирать уже не по чему.
  • Связность. Одно действие пользователя проходит через несколько сервисов. Без общего идентификатора запроса в записях цепочку приходится собирать по совпадению секунд.

Что собирать

Если собирать всё подряд, хранилище забьётся мусором, а нужного в нём не окажется. Разумный минимум такой.

Источник Что даёт Зачем при инциденте
Журналы сервисов приложения ошибки, исключения, длительности операций что именно упало и на каком шаге
Веб-сервер или обратный прокси коды ответов, адреса, время ответа видел ли сервер запрос вообще
База данных долгие запросы, блокировки, аварийные остановки почему операция висела
Брокер сообщений состояние узлов, тревоги по памяти и диску почему задания не двигаются
Системный журнал хостов перезапуски, нехватка памяти, диски почему сервис ушёл без объяснений
Журнал событий безопасности входы, смены прав, массовые выгрузки кто и что делал

Про последнюю строку стоит сказать отдельно. События безопасности обычно уже пишутся системой, их просто никто не забирает. Из них получается ответ на вопрос «кто это сделал» и материал для проверяющих. Что именно писать и на каких граблях теряют половину событий, разобрано в отдельной статье про подсистему аудита Linux.

Как это собирается

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

Из общедоступных сборщиков живут Vector, Filebeat, Fluent Bit и обычный rsyslog; в качестве хранилища чаще всего Elasticsearch или OpenSearch, в корпоративных контурах Splunk, реже Loki. Выбор менее важен, чем три вещи, которые нужно сделать правильно независимо от инструмента:

  1. Привести время к единой зоне на этапе разбора записи, а не при просмотре.
  2. Разобрать запись на поля, а не хранить строкой. Без полей не получится ни отфильтровать по уровню, ни посчитать ошибки по сервисам.
  3. Заранее решить, сколько хранить. Это и есть место, где ошибаются чаще всего.

Ловушка: хранение упирается в число шардов, а не в объём диска

Типовая авария выглядит так. Хранение настроили на две недели, места на дисках с запасом, месяц всё работает. Потом в одно утро панели пустые начиная с полуночи, новые записи не появляются, а диски заполнены наполовину.

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

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

Что с этим делать:

  • Меньше индексов. Не отдельный индекс на каждый сервис, а один на семейство источников с полем, по которому потом фильтруют. Десять индексов в сутки вместо ста решают проблему сразу.
  • Один шард на индекс суточного объёма. Здоровый размер шарда измеряется десятками гигабайт. Дробить на пять шардов индекс размером в гигабайт значит платить за структуру, которая ничего не ускоряет.
  • Копии по необходимости. Одна копия удваивает число шардов. Для журналов, которые не являются единственным источником истины, это не всегда оправдано.
  • Разный срок для разных источников. Шумные вещи вроде журнала доступа веб-сервера редко нужны дольше недели, а события безопасности нужны месяцами. Один срок на всё даёт либо переплату, либо потерю нужного.
  • Следить за числом шардов как за метрикой. Правило простое: «шардов больше восьмидесяти процентов от предела». Оно предупредит за несколько дней до остановки записи.

Поднимать предел вместо наведения порядка можно, но это отложенная плата: кластеру станет тяжелее, а проблема вернётся через месяц на большем масштабе.

Если хранилище Splunk, ловушка другая

В корпоративных контурах логи часто уже собирает Splunk, и туда же логично завести Directum RX, а не поднимать рядом второй стек. Шардов там нет, и предыдущий раздел неприменим. Зато есть три своих подводных камня.

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

Дисциплина типов. В Splunk разбор записи задаётся типом источника. Если каждый сервис RX заводить отдельным типом со своими правилами, поиск по всему приложению превращается в перечисление. Разумнее один тип на семейство журналов приложения и поле с именем сервиса, по которому фильтруют.

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

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

Что сделать

  1. Проверить синхронизацию времени на всех хостах контура. Без этого остальное бессмысленно.
  2. Собрать минимальный набор источников из таблицы выше, начиная с журналов сервисов и веб-сервера.
  3. Разобрать записи на поля при приёме, привести время к единой зоне.
  4. Посчитать число индексов и шардов в сутки до того, как включать хранение на недели.
  5. Настроить разный срок хранения для шумных и ценных источников.
  6. Добавить в наблюдение два правила: «запись в хранилище остановилась» и «приближаемся к пределу»: по числу шардов в Elasticsearch, по суточному объёму приёма в Splunk.

Чего не делать

  • Не собирать всё подряд «на всякий случай». Стоимость хранения и поиска растёт быстрее пользы, а нужное тонет в шуме.
  • Не заводить отдельный индекс на каждый сервис и каждый день. Это самый быстрый путь к потолку по шардам.
  • Не оставлять хранение без явного срока. Молчаливое «храним, пока влезает» заканчивается остановкой записи в самый неподходящий момент.
  • Не считать централизованные логи заменой мониторингу. Логи отвечают на вопрос «что произошло» после события. Чтобы узнать заранее, нужны метрики и правила.