Rsyslogd. Установка и настройка.
При обслуживании большого количества серверов, раньше или позже возникают проблемы поиска информации в логах(системных журналах уведомлений). Нужно найти определенное событие, например прошедшее через несколько серверов письмо. Лезешь на сервер, ищешь лог файл, потом ищешь в нем письмо, переходишь к следующему серверу и т.п. Пока не отследишь письмо. Что бы ускорить процесс поиска, убрав необходимость блуждания по серверам, можно построить отдельный сервер для хранения логов.
Построить его можно на основе обычного syslogd, который входит в базовую FreeBSD.
Но тут есть несколько нюансов. В обычном syslogd сильно ограничены возможности фильтрации. Нет фильтрации по адресу сервера, а только по стандартным syslogовским свойствам. И в итоге получится, что уведомления от всех серверов в один файл. Это первый аргумент в сторону rsyslogd. Rsyslogd позволяет фильтровать по целому ряду признаков. Включая регулярные выражения. Второй аргумент, это возможность использования протокола tcp, в отличии от стандартного udp протокола syslogd. Плюс использования протокола tcp, заключается в том, что отправляющая сторона, контролирует прием записей сервером. И при отсутствии соединения с принимающим сервером, может писать логи на резервный сервер или в локальный файл.
Устанавливать будем и на сервере логов и на клиенте. Устанавливаем из портов на всех точках.
cd /usr/ports/sysutils/rsyslog4 make install clean
А настраивать начнем с клиента. Клиент просто пишет все файлы локально и отправляет все сообщения по tcp на логсервер. Поэтому файл настроек /usr/local/etc/rsyslog.conf выглядит так:
#Принимаем только локальные записи в syslogd по udp $AllowedSender UDP, 127.0.0.1 #Тут описываем права и владельцев локальных файлов $umask 0000 $FileGroup nobody $FileOwner nobody #Шаблон с которым пишутся файлы. Воспроизводит #стандартный syslogd формат $template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n" #Локальные логи. Настройки взяты из стандартного /etc/syslog.conf #только в конце каждого лог-файла описан формат в #котором писать сообщения *.err;kern.warning;auth.notice;mail.crit /dev/console;TraditionalFormat *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err /var/log/messages;TraditionalFormat security.* /var/log/security;TraditionalFormat auth.info;authpriv.info /var/log/auth.log;TraditionalFormat mail.info /var/log/maillog;TraditionalFormat lpr.info /var/log/lpd-errs;TraditionalFormat ftp.info /var/log/xferlog;TraditionalFormat cron.* /var/log/cron;TraditionalFormat *.=debug /var/log/debug.log;TraditionalFormat #Теперь самая интересная часть. Отправляем копию сообщений #на лог сервер по tcp. То что именно по tcp настраивается #количеством символов @. Одно @ - udp, два @ - tcp *.* @@192.168.0.1 # tcp #Приведенные ниже строки отвечают за то, что бы #при отсутствии связи с логсервером не терялись логи. $ActionExecOnlyWhenPreviousIsSuspended on #при исчезновении сервера, логи пишутся в описанный ниже файл #тут можно перед файлом описать один или несколько резервных #лог серверов, тогда в файл будет писаться информация только в том случае, #если все они не доступны. Сервера описываются так: #& @@192.168.1.2 & /var/log/localbuf $ActionExecOnlyWhenPreviousIsSuspended off
Теперь настраиваем сервер. Запускать пока на клиенте не будем. Сначала настроим сервер, запустим и вернемся к клиенту.
На сервере /usr/local/etc/rsyslog.conf выглядит так:
#Загружаем модуль UDP сервера $ModLoad imudp #Pfгружаем модуль TCP сервера $ModLoad imtcp #Загружаем модуль регекспов $ModLoad lmregexp #Принимаем локальные сообщения по UDP $AllowedSender UDP, 127.0.0.1 #От наших серверов по TCP $AllowedSender TCP, 192.168.0.0/24 #Запускаем UDP сервер $UDPServerRun 514 #Запускаем TCP сервер $InputTCPServerRun 514 $umask 0000 $FileGroup nobody $FileOwner nobody $template TraditionalFormat,"%timegenerated% %HOSTNAME% %syslogtag%%msg:::drop-last-lf%\n" #Локальные логи. Что бы не писались записи от всех серверов #вносим в фильтр имя локального сервера. if $hostname contains 'logserv' and (( $syslogfacility-text contains 'auth' and $syslogpriority-text contains 'info' ) or \ ( $syslogfacility-text contains 'authpriv' and $syslogpriority-text contains 'info' )) \ then /var/log/auth.log;TraditionalFormat if $hostname contains 'logserv' and ( ($syslogpriority-text contains 'notice' ) or \ ( $syslogfacility-text contains 'authpriv' and $syslogpriority-text contains 'none' ) or \ ( $syslogfacility-text contains 'kern' and $syslogpriority-text contains 'debug' ) or \ ( $syslogfacility-text contains 'lpr' and $syslogpriority-text contains 'info' ) or \ ( $syslogfacility-text contains 'mail' and $syslogpriority-text contains 'crit' )) \ then /var/log/messages;TraditionalFormat if $hostname contains 'logserv' and ( $syslogfacility-text contains 'mail' and $syslogpriority-text contains 'info' ) \ then /var/log/maillog;TraditionalFormat if $hostname contains 'logserv' and $syslogfacility-text contains 'cron' \ then /var/log/cron;TraditionalFormat if $hostname contains 'logserv' and $syslogfacility-text contains 'security' \ then /var/log/security;TraditionalFormat if $hostname contains 'logserv' and ( $syslogfacility-text contains 'ftp' and $syslogpriority-text contains 'info' ) \ then /var/log/xferlog;TraditionalFormat if $hostname contains 'logserv' and $syslogpriority-text contains 'debug' \ then /var/log/debug.log;TraditionalFormat #Пишем логи от удаленных серверов в свою директорию. if $hostname contains 'logcli' and (( $syslogfacility-text contains 'auth' and $syslogpriority-text contains 'info' ) or \ ( $syslogfacility-text contains 'auth' and $syslogpriority-text contains 'err' ) or \ ( $syslogfacility-text contains 'authpriv' and $syslogpriority-text contains 'info' )) \ then /var/log/logcli/auth.log;TraditionalFormat if $hostname contains 'logcli' and ( ($syslogpriority-text contains 'notice' ) or \ ( $syslogfacility-text contains 'authpriv' and $syslogpriority-text contains 'none' ) or \ ( $syslogfacility-text contains 'kern' and $syslogpriority-text contains 'debug' ) or \ ( $syslogfacility-text contains 'lpr' and $syslogpriority-text contains 'info' ) or \ ( $syslogfacility-text contains 'mail' and $syslogpriority-text contains 'crit' )) \ then /var/log/logcli/messages;TraditionalFormat if $hostname contains 'logcli' and ( $syslogfacility-text contains 'mail' and $syslogpriority-text contains 'info' ) \ then /var/log/logcli/maillog;TraditionalFormat if $hostname contains 'logcli' and $syslogfacility-text contains 'cron' \ then /var/log/logcli/cron;TraditionalFormat if $hostname contains 'logcli' and $syslogfacility-text contains 'security' \ then /var/log/logcli/security;TraditionalFormat if $hostname contains 'logcli' and ( $syslogfacility-text contains 'ftp' and $syslogpriority-text contains 'info' ) \ then /var/log/logcli/xferlog;TraditionalFormat if $hostname contains 'logcli' and $syslogpriority-text contains 'debug' \ then /var/log/logcli/debug.log;TraditionalFormat
В принципе настройки не так уж и сложны. Каждый фильтр представляет это проверка на имя сервера(hostname) и приоритет с фасилити. Естественно для каждого сервера нужно создавать свой фильтр под нужную задачу.
А по сути, каждый фильтр представляет из себя, проверку имени хоста, от которого пришло сообщение, и далее проверку фасилити и приорити. В стандартном syslogd такого не сделаешь. Вообще фильтр rsyslogd можно сделать по любому полю сообщения.
Ну а после того, как мы закончили создавать файлы настроек rsyslogd, разрешим его запускать и запретим запуск штатного syslogd. Для этого сначала остановим syslogd.
/etc/rc.d/syslogd stop
и далее запретим его запускать.
echo 'syslogd_enable="NO"' >> /etc/rc.conf
и разрешим запускаться rsyslogd
echo 'rsyslogd_enable="YES"' >> /etc/rc.conf
и запустим
/usr/local/etc/rc.d/rsyslogd start
Вышеописанную процедуру нужно провести и на сервере и на клиенте.
Фактически настройка rsyslog на этом закончена. Остается перенастроить newsyslog для работы с rsyslog. Об этом я напишу в своей следующей статье.



