DRX INFRA Обсудить задачу

Конфигурация Vector
для журналов Directum RX

Сервисы RX, nginx, PostgreSQL, RabbitMQ и системный журнал пишут каждый в своём формате и в свой часовой пояс. Генератор собирает конфигурацию Vector, которая разбирает всё это на поля, приводит время к одному виду и отправляет в Elasticsearch, Loki или Splunk.

1 · Что собирать

Журналы сервисов RX

2 · Куда и как

Хранилище
Как запускать

3 · Что получилось

    Меняете поле, вывод ниже пересчитывается сразу. Адрес страницы запоминает введённое.

    Что применить

    Один файл конфигурации на сервер. Vector читает новые записи с момента запуска: старые файлы он не перечитывает и хранилище не заваливает.

    Конфигурация

    Сохраните как vector.yaml. Паролей в нём нет: Vector читает их из отдельных файлов в каталоге secrets.

    Включите JavaScript, чтобы увидеть конфигурацию.

    Запуск

    Журналы монтируются только на чтение. Команда tap в конце показывает первые события после разбора: видно, на какие поля разложилась запись.

    
          

    Проверка

    
          

    Вместо паролей в командах стоит CHANGE_ME. Для Vector заведите отдельного пользователя, который может только создавать свои индексы и писать в них. Команды для этого в блоке проверки.

    Что стоит за конфигурацией

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

    Почему Vector

    Один небольшой процесс вместо пары Filebeat и Logstash: читает файлы и системный журнал, разбирает записи на месте и отправляет сразу в хранилище. Разбор пишется на его языке VRL, который проверяется при запуске: опечатка в правиле не даст Vector стартовать, а не тихо испортит данные. На сервер уходит 100–200 МБ памяти, в команде запуска стоит предел 512 МБ.

    Журналы сервисов RX

    Сервисы RX пишут журнал строками JSON, одна запись на строку. Состав полей описан в документации вендора: t время с часовым поясом, l уровень, mt текст сообщения, ex исключение со стеком, span операция и её длительность, lg логгер, tr трассировка, un учётная запись. Конфигурация выносит наверх то, по чему ищут: сервис (из имени файла), уровень, текст, логгер, пользователя, тип исключения, стек, метод, в котором оно случилось, операцию и её длительность в миллисекундах. Остальное лежит в поле rx.

    У предупреждений и ошибок появляется поле genericMessage: тот же текст, где адреса, пути, GUID, числа и строки в кавычках заменены заглушками. «Document 18234 not found» и «Document 90211 not found» становятся одной строкой, и по ней видно, какая ошибка самая частая, а не какая последняя. Ошибки уходят в отдельный индекс: их хранят дольше, а ищут чаще.

    Поля mt, args, cust и span у разных записей бывают то строкой, то объектом. Elasticsearch такую запись отвергает с конфликтом типов, поэтому они сохраняются строкой JSON. Веб-агент пишет пути Windows с одиночным обратным слешем, строгий разбор JSON на этом падает: конфигурация такие строки чинит, а не теряет.

    Время и часовой пояс

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

    PostgreSQL: одна запись вместо пяти строк

    Ошибка PostgreSQL занимает несколько строк: сама ошибка, DETAIL с подробностями, STATEMENT с текстом запроса, иногда HINT и CONTEXT. Если отправлять их по отдельности, в хранилище окажется «deadlock detected» без запроса, который его вызвал. Конфигурация склеивает их в одну запись и раскладывает по полям: pg.statement, pg.detail. Ещё она определяет вид записи pg.kind: медленный запрос с длительностью, чекпоинт с числом буферов и временем, автовакуум с таблицей, временный файл с размером, блокировка, подключение. По этим полям строятся панели без разбора текста на лету. Строки pg_probackup, которые попадают в тот же журнал без префикса, тоже распознаются.

    Журнал аудита: кто на самом деле

    Одно событие auditd это несколько строк с общим номером, связать их можно по полю audit.id. Поле auid показывает того, кто вошёл в систему, и не меняется после su и sudo, поэтому отвечает на вопрос «кто это сделал» точнее, чем uid. Команду sudo auditd записывает шестнадцатеричной строкой: конфигурация переводит её в текст, иначе её не прочитать ни глазами, ни поиском. Неудачные попытки получают уровень warn.

    Один индекс на источник в сутки

    Индексы называются по семейству источника: журналы RX, nginx, PostgreSQL и так далее, по одному в сутки. Отдельный индекс на каждый сервис RX быстро съедает лимит шардов. Подробно эта ловушка разобрана в статье о журналах RX, а срок хранения под ваш диск считает калькулятор Elasticsearch: начало имени индексов в нём то же.

    Пароли отдельными файлами

    Во многих инструкциях пароль подставляют в конфигурацию из переменной окружения записью вида ${ES_PASSWORD}. В свежих версиях Vector так больше не работает: подстановка выключена по умолчанию, и в хранилище уходит буквальная строка с долларом, а в ответ приходит ошибка 401. Включить её можно флагом с говорящим названием --dangerously-allow-env-var-interpolation. Мы используем встроенное хранилище секретов Vector: каждый пароль лежит отдельным файлом, читать который может только сам Vector.

    Буфер на диске

    Если хранилище недоступно, Vector складывает события в буфер на диске объёмом до гигабайта и дошлёт их, когда хранилище вернётся. Без буфера события за время недоступности пропадут, а это как раз то время, когда журналы нужнее всего.

    Что отбрасывается

    Отладочные записи RX и запросы nginx к статике и проверкам доступности. Из системного журнала исключён журнал самого Vector: его ошибки отправки, отправленные в то же хранилище, дают петлю ровно тогда, когда хранилищу и так плохо. Записи длиннее 64 КБ обрезаются с пометкой message_truncated. На нагруженной системе это больше половины объёма, а при разборе инцидента они не нужны. Ответы nginx с ошибкой не отбрасываются никогда, даже для статики.

    Метрики самого Vector

    Сборщик журналов тоже ломается, и узнают об этом обычно в момент, когда журналы понадобились. На порту 9598 Vector отдаёт метрики для Prometheus: ошибки разбора и отправки, заполнение буфера, число событий по источникам. Правило тревоги простое: ошибки отправки растут или буфер заполняется.

    Чего генератор не делает: не настраивает панели и поиск в хранилище и не разбирает журналы Windows. Под Windows Vector работает так же, но источники там другие: журнал событий и файлы IIS.

    Девять мест, где сборщик теряет записи молча. Разбор

    Запись не уходит в хранилище, Elasticsearch отвечает ошибкой. Справочник ошибок