Syslog-ng PE и Elasticsearch: переводим централизованный syslog с rsyslog
Как мы перевели крупного клиента с rsyslog на syslog-ng PE 3.3, подружили JSON-события с Elasticsearch и на что наступили в процессе.
Syslog-ng 3.3 добавил встроенную поддержку MongoDB и JSON-формат для структурированных логов
У клиента - сеть примерно из трёх сотен серверов под CentOS и RHEL, россыпь сетевых железок и несколько Windows-машин с nxlog. Логи собирались на rsyslog-агрегатор, писались в файлы, дальше периодически скриптами перекладывались куда придётся. Поиска как такового не было: когда что-то случалось, инженер шёл с grep по архивам. Нас позвали разобраться.
Задача сформулировалась так: структурированные логи, нормальный поиск, никаких лишних посредников. Elasticsearch к тому моменту уже работал у них для другой задачи, так что вопрос «куда писать» снялся сам.
Почему именно syslog-ng PE, а не rsyslog дальше. rsyslog умеет JSON и умеет elasticsearch через плагин, но конфигурация у него превращается в страшный сон довольно быстро. Syslog-ng PE 3.3 дал встроенный format-json() прямо в destination и нормальную читаемую грамматику конфига. Плюс поддержка MongoDB вышла в том же релизе - на случай если клиент захочет ещё и NoSQL-хранилище. Enterprise-версия нужна была из-за поддержки и SLA: open-source syslog-ng тут тоже заработал бы, но клиент хотел вендорскую поддержку.
Конфиг-ядро выглядит примерно так:
source s_network {
udp(ip("0.0.0.0") port(514));
tcp(ip("0.0.0.0") port(514) max-connections(300));
};
template t_json {
template("$(format-json --scope rfc5424 --key .* --rekey .* --upper-case NO)");
template-escape(no);
};
destination d_elastic {
http(
url("http://es-node:9200/syslog-$(year)-$(month)-$(day)/_bulk")
method("POST")
headers("Content-Type: text/plain")
body("{ \"index\": {} }\n$(t_json)\n")
flush-lines(100)
);
};
log {
source(s_network);
destination(d_elastic);
flags(flow-control);
};
Это упрощённо; в реальном конфиге добавился парсинг syslog-сообщений через syslog-parser(), несколько веток с фильтрами по facility и program, и отдельный поток для Windows-хостов, где поле MESSAGE было в другой кодировке.
Первый подводный камень - кодировка. Windows через nxlog слал UTF-16LE в поле сообщения. syslog-ng аккуратно передавал это как есть в JSON, Elasticsearch индексировал, но при поиске половина кириллицы расходилась. Добавили rewrite с set-charset("UTF-8") перед передачей - помогло, но не на всех хостах. На некоторых nxlog был настроен отдавать уже в UTF-8, а принудительная конвертация ломала их сообщения. Пришлось разбить на два source с разными обработчиками, идентифицируя Windows-хосты по HOST.
Второй камень - объём и bulk API. Elasticsearch принимает документы через bulk-интерфейс пакетами. syslog-ng PE 3.3 умеет http() destination, но тогда bulk-формат нужно собирать вручную через шаблон. Мы промахнулись с форматом на старте: забыли \n после каждого action-объекта, и Elasticsearch молчаливо отбрасывал пакеты. Дебаггинг был нервным - в ответе ES возвращал 200 OK с errors: true внутри тела, а syslog-ng это за ошибку не считал. Добавили отдельный лог bulk-ответов через curl-скрипт и тогда увидели картину.
Третий камень - ротация индексов. Мы сразу делали индексы по дням (syslog-2012-03-19), что правильно. Но template в Elasticsearch нужно было создать заранее - иначе ES сам угадывал типы полей, и одно поле priority попало как string на первый день и как long на второй, после чего поиск по нему рассыпался. Шаблон с явной маппингом поправил это.
Что в итоге. После двух недель пилота логи пошли в ES стабильно, поиск работает, команда клиента за полчаса нашла корреляцию между событиями на трёх разных хостах - то, что раньше требовало дня работы с grep. Агрегатор syslog-ng PE держит нагрузку без видимого напряжения.
Открытый вопрос - аутентификация на Elasticsearch: сейчас кластер смотрит только во внутреннюю сеть и без TLS. Для регулируемой среды это придётся закрывать отдельно, и встроенного решения в базовом ES на тот момент нет - надо либо nginx-прокси с basic auth, либо коммерческие плагины.
Подобная работа - часть того, чем мы занимаемся в рамках сопровождения инфраструктуры. Если rsyslog в вашей инфраструктуре уже превратился в коллекцию скриптов-обёрток - стоит смотреть в сторону syslog-ng или logstash, пока объём ещё управляем.
- Взломали роутер, логи стёрты: настраиваем центральный syslog-сервер · 4 сентября 2002
- Центральные логи безопасности: видеть картину целиком, а не по кускам · 6 декабря 2005