Отправка json через rsyslog в elasticsearch — Администрирование devops сопровождение проектов

Отправка 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
       
Другие новости
03.08.2024
Сервер упал «вчера» или назад в будущее. Настраиваем atop!

Всем привет доброго лета! Задача из уст заказчика звучала следующим образом : \»мониторинг яндекса сказал что сайт не работает, при этом сервер пингуется\». Ну первым делом лезу на подвластный мне сервер, смотрю логи : аптайм 100 дней, перезагрузок не было

Хранение конфигурационных файлов в Git (Gitlab)

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