Ведение системных журналов, т.н. логов, является важной частью любой вычислительной системы. Системные записи позволяют мониторить состояние системы, выявлять проблемные и узкие места в ней. Т.о. лог, это место куда система, приложение или что-либо еще могут сообщить о своих проблемах, где админ может узнать что же там происходит. Значимым вопросом является организация работы с логами. В FreeBSD предусмотрен демон syslogd, в котором реализованы требования одноименного стандарта. Указанный демон реализует базовые принципы работы протокола syslog. Он достаточно прост и понятен. В тоже время, в силу своей простоты, его возможности сильно ограничены. В частности, он не умеет в режиме реального времени парсить получаемые сообщения и осуществлять на основе анализа определенное действия, вести запись в СУБД и т.д. Поэтому все просто когда компьютер один, а что если их сто, а то и больше... Вот на этом моменте я хотел бы отметить пару более функциональных и известных аналогов — rsyslog, syslog-ng. Далее в статье, пойдет речь об rsyslog. Почему я его выбрал? Все просто, так "легли карты".
Rsyslog — высокопроизводительный аналог системного демона syslog, имеющий модульную архитектуру, более гибкий в настойке. По заявлению разработчиков, достаточно быстр, настолько, что позволяет обрабатывать миллион сообщений в секунду. Неплохо, да? И что более важно, в частности для меня, умеет вести системный журнал в СУБД. А раз системные записи хранятся в структурированном виде, соответственно их проще обрабатывать. Еще отмечу, что для комфортного просмотра таких записей отдельной группой разработчиков развивается веб-морда LogAnalyzer. Очень удобно, тем более, что большая часть функций доступа практически из коробки. Ну что же, пора от слов к делу...
Установку и настройку rsyslog я буду осуществлять на FreeBSD версии 11.1. На момент написания статьи в портах доступна версия rsyslog 8.31.0. Итак, идем в порты и устанавливаем его:
- # cd /usr/ports/sysutils/rsyslog8
- # make install clean
Из доступных опций компиляции я выбрал следующие:
- DOCS — установить с пакетом документацию;
- GCRYPT — позволяет шифровать логи;
- JSONPARSE — парсер файлов в формате JSON;
- PGSQL — поддержка СУБД PostgreSQL в качестве хранилища системных журналов;
- CREATE DATABASE "Syslog" WITH ENCODING 'SQL_ASCII' TEMPLATE template0;
- \c Syslog;
- CREATE TABLE SystemEvents
- (
- ID serial not null primary key,
- CustomerID bigint,
- ReceivedAt timestamp without time zone NULL,
- DeviceReportedTime timestamp without time zone NULL,
- Facility smallint NULL,
- Priority smallint NULL,
- FromHost varchar(60) NULL,
- Message text,
- NTSeverity int NULL,
- Importance int NULL,
- EventSource varchar(60),
- EventUser varchar(60) NULL,
- EventCategory int NULL,
- EventID int NULL,
- EventBinaryData text NULL,
- MaxAvailable int NULL,
- CurrUsage int NULL,
- MinUsage int NULL,
- MaxUsage int NULL,
- InfoUnitID int NULL ,
- SysLogTag varchar(60),
- EventLogType varchar(60),
- GenericFileName VarChar(60),
- SystemID int NULL
- );
- CREATE TABLE SystemEventsProperties
- (
- ID serial not null primary key,
- SystemEventID int NULL ,
- ParamName varchar(255) NULL ,
- ParamValue text NULL
- );
Стоит отметить, что перед созданием таблиц, я немного изменил данный файл, а именно заменил тип serial на bigserial и переименовал БД.
Конфигурационный файл rsyslog располагается по следующему пути /usr/local/etc/rsyslog.conf. У меня конфигурация полностью заменяет стандартный системный syslog, имеет некоторые дополнения и улучшения. Формат конфигурационного файла, так сказать, не совсем однозначен. Исходя из документации, представленной на официальном сайте, текущая версия rsyslog поддерживает одновременно два разных способа задания директив — старый (практически как в системном syslog.conf) и новый (RainerScript). При этом их можно комбинировать. Видимо в настоящее время разработчики работают над новым синтаксисом и потихоньку уходят от старого. Однако, некоторые модули поддерживают директивы только в старом синтаксисе. В общем, внимательно смотрите документацию к конкретным модулям.
У меня конфигурационный файл выглядит следующим образом:
- # RSyslog configuration
- # Глобальные параметры (заданы в новом формате и старом, т.е. иногда приходится дублировать)
- # -------------------------------------------------------------------
- global(workDirectory="/var/spool/rsyslog")
- $WorkDirectory /var/spool/rsyslog
- $ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
- # Подключаемые модули
- # -------------------------------------------------------------------
- module(load="immark") # поддержка сообщений типа --MARK-- (в спецификации протокола syslog написано, что это за сообщения)
- module(load="imuxsock") # позволяет принимать логи по сети посредством локальных сокетов
- module(load="imklog") # включаем поддержку сообщений от ядра ОС
- module(load="imudp") # позволяет принимать логи по сети посредством UDP
- module(load="ompgsql") # включаем поддержку СУБД
- # Конфигурация модулей, осуществляющих прием сообщений
- # -------------------------------------------------------------------
- # Обработка логов на 514 порту
- input(type="imudp" port="514" ruleset="rs_remote")
- # Шаблоны
- # -------------------------------------------------------------------
- # Шаблон, используемый для записи в СУБД (прим. SQL запрос в одну строку)
- template(name="t_dbsql" type="string" option.stdsql="on"
- string="INSERT INTO SystemEvents (Message, Facility, FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag, ProcessID)
- VALUES ('%msg%', %syslogfacility%, '%HOSTNAME%', %syslogpriority%, '%timereported:::date-pgsql%', '%timegenerated:::date-pgsql%', %iut%, '%syslogtag%', '%procid%')"
- )
- # Output channels (правила ретрансляции)
- # -------------------------------------------------------------------
- #
- # Правила обработки сообщений (ruleset + selector)
- # Здесь я использовал как старый синтаксис, так и новый.
- # -------------------------------------------------------------------
- *.err;kern.warning;auth.notice;mail.crit /dev/console
- *.notice;authpriv.none;kern.debug;lpr.info;mail.crit;news.err /var/log/messages
- security.* /var/log/security
- auth.info;authpriv.info /var/log/auth.log
- mail.info /var/log/maillog
- lpr.info /var/log/lpd-errs
- ftp.info /var/log/xferlog
- cron.* /var/log/cron
- if not ($programname startswith "devd") then {
- if ($syslogseverity-text == "debug") then {
- action(type="omfile" file="/var/log/debug.log" )
- }
- }
- if ($syslogseverity-text == "emerg") then {
- action(type="omusrmsg" users="*")
- }
- # uncomment this to log all writes to /dev/console to /var/log/console.log
- # touch /var/log/console.log and chmod it to mode 600 before it will work
- if ($syslogfacility-text == "console"
- and $syslogseverity-text == "info")
- then {
- action(type="omfile"
- file="/var/log/console.log"
- fileCreateMode="0600"
- )
- }
- if ($programname startswith "ppp") then {
- action(type="omfile" file="/var/log/ppp.log")
- stop
- }
- # Дублируем все сообщения в БД (обратите внимание, директивы заданы в старом синтаксисе)
- $ActionQueueType LinkedList # включаем асинхронную обработку полученных сообщений, указывая способ формирования очереди
- $ActionQueueFileName dbq # имя файла, где будет создаваться очередь на запись (файл создается в рабочей директории, заданной через workDirectory)
- $ActionResumeRetryCount -1 # количество попыток записи в БД сообщения
- *.* :ompgsql:127.0.0.1,DBNAME,USERNAME,PASSWORD;t_dbsql
- stop
- # Обработка сообщений, полученных по сети
- ruleset(name="rs_remote"){
- # Пишем все сообщения с удаленных хостов в БД
- $ActionQueueType LinkedList # см. выше
- $ActionQueueFileName dbq # см. выше
- $ActionResumeRetryCount -1 # см. выше
- *.* :ompgsql:127.0.0.1,DBNAME,USERNAME,PASSWORD;t_dbsql
- }
Обновление от 16.01.2018. Разработчики rsyslog 09.01.2018 выпустили новую версию своего продукта - 8.32.0, в которой внесли ряд изменений и улучшений. В частности, был переработан модуль ompgsql, в результате настраивать взаимодействие с СУБД PostgreSQL можно с использованием новых директив. Вот так теперь будет выглядеть отправка сообщений в БД:Отмечу, что пока поддерживается обратная совместимость, но в скором я думаю, разработчики прекратят поддержку директив в старом синтаксисе для данного модуля.
action(type="ompgsql" server="localhost" user="USER" pass="PASSWORD" db="DBNAME" template="t_dbsql" queue.size="10000" queue.type="linkedList" queue.workerthreads="5" queue.workerthreadMinimumMessages="500" queue.timeoutWorkerthreadShutdown="1000" queue.timeoutEnqueue="10000" )
Думаю большинство записей конфигурационного файла должно быть понятно, а где было необходимо я добавил комментарии. Хочется отметить, у меня долго не получалось разобраться как же все таки правильно писать правила, поскольку разработчики решили создать новый синтаксис директив, а актуализация документации на официальном сайте немного отстает от темпов разработки. Поэтому, в качестве дополнительно источника знаний, кроме документации на ПО, стоит использовать еще и вики.
Итак, теперь необходимо внести еще парочку изменений в системный файлы и можно пробовать запускать rsyslog.
- # echo 'syslogd_enable=NO' >> /etc/rc.conf
- # echo 'rsyslogd_enable=YES' >> /etc/rc.conf
- # echo 'rsyslogd_config=/usr/local/etc/rsyslog.conf' >> /etc/rc.conf
- # echo 'rsyslogd_pidfile=/var/run/syslog.pid' >> /etc/rc.conf
- # service syslogd forcestop
- # service rsyslog start
Проверяем , запустился ли сервис:
- # ps -ax | grep rsyslog
- 27446 - Is 1:20,52 /usr/local/sbin/rsyslogd -i /var/run/syslog.pid -f /usr/local/etc/rsyslog.conf
Если вы видите, что-то подобное, то сервис запустился и начал работать. В текущей конфигурации, информацию о собственных проблемах rsyslog будет писать в /var/log/messages, поэтому, если что-то не работает, то в первую очередь смотрите туда. А если не получилось разобраться, то задавайте вопросы на форуме, попробуем помочь. В начале статьи я упомянул про веб-морду к rsyslog, так вот настройка ее не представляет собой ничего сложного, для ее запуска нужен работающий веб-сервер с PHP и немного пространства на нем (ссылка на LogAnalyzer приведена ниже).
пн, 28/11/2022 - 08:02
В newsyslog нужно добавить pid rsyslog, для правильной ротации логов. pid syslog уже вшит в код newsyslog, поэтому там не указыается.