Ноя 17 2009

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. Об этом я напишу в своей следующей статье.

Добавить в закладки:

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

Украинская Баннерная Сеть