Comments 12
Как воспроизвести
источник
module(load="imfile" mode="inotify")
input(type="imfile"
File="/var/log/1.log"
Tag="FILE_test:")
module(load="omrelp")
:syslogtag, startswith, "FILE" action(type="omrelp" target="192.168.1.101" port="2514"
action.resumeRetryCount="-1"
queue.type="Disk"
queue.filename="queue.logremote"
queue.discardmark="1000000"
queue.size="1000001"
queue.maxfilesize="10m"
queue.maxdiskspace="4g"
queue.saveonshutdown="on")
приемник
module(load="imrelp")
input(type="imrelp" port="2514")
$template DYNtest,"/var/log/%HOSTNAME%/1.log"
#crop leading space
$template MSG,"%msg:2:999999999%\n"
:syslogtag, isequal, FILE_test: ?DYNtest;MSG
Далее погасить rsyslog на приемнике для имитации проблем с сетью
На источнике выполнить for i in {1..100000}; do echo $i >> /var/log/1.log; done
Запустить rsyslog на приемнике и сравнить что прилетело в /var/log/%HOSTNAME%/1.log
Спасибо. Как будет время — проверю на последней версии и пойду пинать разработчиков на гитхабе.
Тикет закрыли как "expected behaviour". Судя по http://www.rsyslog.com/doc/v8-stable/concepts/queues.html#performance, это действительно так для дефолтного queue.dequeuebatchsize=16
, а queue.dequeuebatchsize=1
это вылечит, но негативно скажется на производительности. Как будет время — поэкспериментирую с этим и обновлю статью.
Спасибо автору за проделанную и детально описанную работу. При этом хотелось бы отметить, что rsyslog — это архаичный, неудобный и крайне ненадежный инструмент, особенно если пытаться использовать его в конфигурации, отличной от базовой, или в достаточно сложных системах.
Помимо упомянутой в другом комментарии проблемы с порядком доставки, есть еще следующие "прелести":
- внезапное"затыкание" очереди и полная остановка клиентской системы в случае недоступности центрального сервера (лечится возвратом к UDP или созданием отдельной очереди на клиенте и тонкой её настройкой);
- создание отдельного TCP-соединения на каждую строку вида @@ (для пересылки логов на сервер), что не является проблемой для клиента, но существенно для сервера при большом количестве подобных клиентов;
- низкая производительность центрального сервера (при более чем 400-500 активных входящих соединений и небольшом количестве правил анализа сообщений), при переходе на syslog-ng нагрузка падает в 5-8 раз;
- в отдельных версиях с пересылкой FQDN на центральный сервер при корректных настройках клиента передается только "короткое" имя сервера (известный баг).
- непрозрачный и неудобный синтаксис (о чем, впрочем, уже было упомянуто в статье), нетривиальные правила разбора и изменения сообщений.
Несмотря на то, что мы изначально решили поставленные задачи исключительно на базе rsyslog, эта конфигурация постоянно требовала поддержки и исправления костылей, поэтому в итоге решено было переключиться на syslog-ng.
создание отдельного TCP-соединения на каждую строку вида @@ (для пересылки логов на сервер)
Лечится выносом соединения в RuleSet и вызовом его для отправки call myruleset
, как описано в статье. Получается только одно соединение.
в отдельных версиях с пересылкой FQDN на центральный сервер при корректных настройках клиента передается только "короткое" имя сервера
Это наверное какие-то старые версии, ну и в крайнем случае можно переопределить шаблон для отправки
А в syslog-ng можно как-то использовать внешний обработчик для изменения логов перед сохранением/отправкой? Регэксп можно, но чтобы фильтровать номера карт без кучи ложных срабатываний, надо проверять корректность по алгоритму Луна, а этого регэкспом не сделаешь
А в syslog-ng можно как-то использовать внешний обработчик для изменения логов перед сохранением/отправкой?
Можно. Мы крутим на Perl, которому логи подаются через STDIN. Поток для преобразования (все сообщения категории LOCAL2) примерно 600-800 сообщений в секунду.
filter f_local2 {
facility(local2)
};
destination d_parser {
program("/usr/local/bin/parser.pl" template("${R_UNIXTIME} ${HOST} ${MSG}\n"));
};
log {
source(s_net); filter(f_local2); destination(d_parser); flags(final);
};
Внешний скрипт может либо в файл писать, либо назад закидывать через syslog-библиотеку.
Добавлю: создавать отдельне TCP-соединие на каждую строку вида @@ в общем логично: это отдельные Action
, у них могут быть свои настройки шаблона, очереди, других параметров действия. Если в syslog-ng сделать кучу destination
, он тоже скорее всего создаст для каждого из них отдельное соединение.
Но да, в syslog-ng оптимальную конфигурацию написать проще, а в rsyslog проще пользоваться legacy-синтаксисом и написать неоптимальную :(
Cбор логов с rsyslog, именами файлов в тегах, многострочными сообщениями и отказоустойчивостью