Pull to refresh

Comments 12

у очередей rsyslog-а есть один неприятный момент. они гарантируют доставку после восстановления сети. но не гарантируют порядок доставки. на моих тестах rsyslog перемешивал строки лога. причем похоже это происходило на отправителе, а не на принимающем центральном лог сервере. для сравнения syslog-ng лог не перемешивает.
У нас такого пока вроде не замечал, надо будет проверить. Если есть чёткий алгоритм воспроизведения проблемы — можно написать разработчикам на гитхаб: https://github.com/rsyslog/rsyslog/issues

Как воспроизвести


источник


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 это вылечит, но негативно скажется на производительности. Как будет время — поэкспериментирую с этим и обновлю статью.

странно. syslog-ng это как-то делает без падения производительности

Статью обновил. Эксперименты показали, что 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-синтаксисом и написать неоптимальную :(

Sign up to leave a comment.

Articles