Отправка json через rsyslog в elasticsearch

Отправка json через rsyslog в elasticsearch

В предыдушей статье было описано как затолкать в elasticsearch данные syslog. Но довольно часто возникает необходимость разбирать груды логов от приложений программистов, бегать по серверам не по джадайски конечно, поэтому используем тот же самый syslog для доставки сообщений от приложения в elasticsearch, из которого удобно смотрим и фильтруем кибаной. Кроме того так же складываем туда же логи docker контейнеров. Суть проста — приложение использую системный вызов syslog пишет сообщение  в него, это очень простая и быстрая операция. Дальше сообщение пересылается на удаленный сервер логирования, где происходит его разбор и отправка в эластик. Процесс этот при правильной подготовке гарантирует 100% надежность (используется tcp)  и занимает пару секунд времени даже на медленных каналах.

Локальная пересылка и настройка удаленного сервера логирования была описана в предыдущей статье, для понятности в этой статье коротко повторю. Так же заранее договариваемся с программистами чтобы использовали правильные теги для своих логов. Мы договорились все теги начинать с docker_app_ — позже в статье этот тег будет применяться для разбора и шаблонирования.

Для отправки логов неоходимо создать файл  /etc/rsyslog.d/rsyslog-server.conf со следующим содержимым:

$ActionQueueType Direct
$ActionResumeRetryCount -1 #пытаться отправить бесконечно
$ActionQueueSaveOnShutdown on # При завершении работы сбросить очередь на диск
*.* @@syslogserver.casp.ru/old:514

После чего перезапустить rsyslogd.

 

Далее необходимо подготовить наше приложение. Тут два обязательных условия:

  • валидный json
  • наличие поля @timestamp, это дата в формате rfc3999 (RFC3339 = «Y-m-d\TH:i:sP» )

Вот пример пхп кода для отправки сообщений в сислог:

<?php
openlog("docker_app_pophp7_error_testjson", LOG_PID | LOG_PERROR, LOG_LOCAL0);

$data['@timestamp'] = date('c');
$data['text'] = 'test message';
$data['host'] = 'host1';
syslog(LOG_ERR, json_encode($data));

?>

 

Дале повторю часть конфига из предыдущей статьи, в данном контексте это в пояснении не нуждается, и далее идет описание тесплейтов для записи в файловую систему принимающего syslog сервера, записи в эластик сообщений самого сислог и обработки сообщений json который присылают наши программисты.

$ModLoad imudp
$UDPServerRun 514
$ModLoad imtcp
$InputTCPServerRun 514

$PreserveFQDN on

$template RemoteHost,"/var/log/remote/%HOSTNAME%/syslog.log"


module(load="omelasticsearch")

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-json"
type="list") {
constant(value="syslogjson-")
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")
}
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")
}

template (name="rawmessage-json" type="string" string="%msg%")

И как кульминация — разбор и распихивание логов по файловой системе и разным индексам эластика в зависимости от тега.

if $programname startswith 'docker_app' or $syslogtag startswith 'docker_app' then { 
*.* action(type="omelasticsearch"
server="127.0.0.1" # destination Elasticsearch host
serverport="9200" # and port
template="rawmessage-json"
searchindex="syslog-json"
dynSearchIndex="on")
} else {
*.* action(type="omelasticsearch"
server="127.0.0.1" # destination Elasticsearch host
serverport="9200" # and port
template="plain-syslog"
searchIndex="syslog-index"
dynSearchIndex="on")
*.* ?RemoteHost
}

Обычные сообщения мы кладем в индекс syslog а json в индекс syslogjson, темплейты были заданы выше.

 

После чего можем наблюдать сообщения в кибане.

 

Возможные трудности:

  • Обязательно надо включать поле @timestamp в json, без него кибана не даст завести в себя новый индекс.
  • Для ускорения доставки при отправке на сервере надо указывать  параметр $ActionQueueType Direct

 

 

 

 

Другие новости
21.05.2019
Настойка satis для пакетов composer в docker

Настрройка satis satis — кеширующий сервер для пакетов php composer. Для настройки репозитория будем использовать официальный docker. Разработчикам понадобится редактировать файла конфигурации satis.json, для этого поднимем отдельный контейнер с sftp и ftp серверами внутри. Файл конфиргурации в нашем случае должен

27.07.2018
Лечим wordpress https err_too_many_redirects

По какой логике wordpress понимает что к нему пришел https не понятно, но часто сталкиваемся с проблемой когда стили и js вордпресс отдает  по http и изза mixed content браузеры их режут. Если в настройках (Настройки -> Общие) жестко указали