При администритовании парка серверов примерно от 10 и выше, возникает необходимость в централизованном хранении логов.
Целей тут несколько.
- Во первых безопасность — все фиксируется, и дублируется не только локально, но и на удаленном сервере. Если взломают сервер и потрут логи, то в частном случае можно будет восстановить что и когда было сделано; кем и откуда.
- Второй момент — удобная обработка логов. Логи можно быстро затолкать в эластик и через интерфейс kibana легко смотреть что происходит, строить зависимости и тд.
- Третий, важный момент — единая с программистами среда разбора логов. Можно сопоставлять время того или иного событиям по определенным критериям с событиями на других серверах, обычно этот критерий является основным для внедрения централизованной хранилки логов.
- Есть еще один очень важный момент в крупных кампаниях — протокол syslog очень удобно использовать для доставки сообщений не только от серверов но и от приложений, кронов и прочего в хранилку. Плюс тут в существенном росте производительности — приложению не требуется ни открывать файл на диске, ни тем более соединятсья по сети с elasticsearch — все что нужно это записать данные в syslog сокет. Дальше при правильной настройке доставка произойдет средствами самого сислога, а процесс продолжит свою работу без существенных задержек.
Приступаем. На большинстве серверов в коробке уже стоит rsyslogd, который помимо всего прочего умеет отправлять логи в elasticsearch. Это очень круто, так как не требуется лишнее звено в виде logstash!
Для надежности в эластике мы будем дублировать логи в эластике и на диске.
Для пересылки у нас используется tcp, т.к. сеть большая, с несколькими впн туннелями, накладных расходов от такого подхода — 100мс, на установку соединения, а терять логи не по джадайски. Конфиг для передающей стороны выглядит следующим образом:
# cat /etc/rsyslog.d/rsyslog-server.conf $MaxMessageSize 65536 $ActionQueueType Direct $ActionResumeRetryCount -1 #пытаться отправить бесконечно $ActionQueueSaveOnShutdown on # При завершении работы сбросить очередь на диск *.* @@syslogserver.casp.ru/old:514
Тут параметр $ActionQueueType Direct подбирался экспериментально, в скупой официальной документации на эту тему сказано ровно следующее:
queue.type [FixedArray/LinkedList/Direct/Disk]
Экспериментально было выяснено:
- LinkedList — асинхронный режим, при получении больших сообщений не передает их сразу а некоторое время ожидает, до полуминуты.
- Direct — синхронный режим, быстро и сразу передает сообщения
- Disk — сихнронный самый медленный режим, предполагающий все сообщения вместе с передачей писать в очередь на диск
- FixedArray — не экспериментировл, но по смыслу похоже на LinkedList
И далее на принимающем сервере создаем следующий конфиг:
# cat /etc/rsyslog.d/remotelogger.conf $MaxMessageSize 65536 $ModLoad imudp $UDPServerRun 514 $ModLoad imtcp $InputTCPServerRun 514 $PreserveFQDN on $template RemoteHost,"/var/log/remote/%HOSTNAME%/syslog.log" *.* ?RemoteHost
Тут все просто и внимание стоит обратить на две последние строчки — создаем темплейт по которому будут писаться сообщения в файловой системе и в последней строке пишем.
В первых же 4х строках мы открыли на прием стандартные порты на tcp и udp.
В обоих случаях необходимо указывать $MaxMessageSize желательно заметно больше ожидаемой длины пакета.
Теперь самое вкусное — запись логов в elasticsearch. В том же кониге создаем два темплейта. Первый переведет полученные данные в json и подготовит для загрузки в elasticsearch, второй определяет индекс для отправки логов в самом эластике:
template (name="plain-syslog" type="list") { constant(value="{") constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339") constant(value="\",\"host\":\"") property(name="hostname") constant(value="\",\"severity\":\"") property(name="syslogseverity-text") constant(value="\",\"facility\":\"") property(name="syslogfacility-text") constant(value="\",\"tag\":\"") property(name="syslogtag" format="json") constant(value="\",\"message\":\"") property(name="msg" format="json") constant(value="\"}") } template(name="syslog-index" type="list") { constant(value="syslog-") property(name="timereported" dateFormat="rfc3339" position.from="1" position.to="4") constant(value=".") property(name="timereported" dateFormat="rfc3339" position.from="6" position.to="7") constant(value=".") property(name="timereported" dateFormat="rfc3339" position.from="9" position.to="10") }
Следующим шагом загружаем модуль вывода данных в эластик и отправляем в него данные по шаблону определенному выше:
module(load="omelasticsearch") *.* action(type="omelasticsearch" server="127.0.0.1" # destination Elasticsearch host serverport="9200" # and port template="plain-syslog" searchIndex="syslog-index" dynSearchIndex="on")
По теме rsyslog на этом месте можно закончить! Не расскрытой осталась тема работы с kibana.
Если у Вас она еще не стоит, то вот простой рецепт. Создаете файл docker-compose.yml следующего содержимого на этот же сервер:
elasticsearch: image: elasticsearch:latest container_name: elastic command: elasticsearch -Des.network.host=0.0.0.0 #net: host ports: - "127.0.0.1:9200:9200" volumes: - "/srv/docker/elastic/db:/usr/share/elasticsearch/data" restart: always kibana: image: kibana restart: always container_name: kibana links: - elasticsearch:elasticsearch ports: - "5601:5601"
После чего выполняем в папке с этим файлом команду docker-compose up -d, далее происходит скачка, установка и запуск контейнеров. Сразу же после запуска в эластк начнут поступать данные из сислога, а в кибану мы сможем попасть по порту 5601 (отпубликованному в конфиге выше). Нам остается в кибане создать индекс syslog- и начать пользоваться фильтрами.