В стопиццотый раз хотелось бы затронуть тему централизованного ведения логов.
Получим в журнал ошибок два сообщения, одно со статусом еррор, второе варнинг !
Рано или поздно, любой системный администратор, задается вопросом "Как бы сделать так что бы еще больше ничего не делать...?" И тут уже начинается и полет фантазии, и автоматизация, и изучение языков программирования и так далее. Прилагаются титанические усилия в кратчайшие сроки, что в переводе на "работо-часы" означает что проделанной работы хватило бы на целый квартал, но нет же !!! Нужно обязательно поделить работу на 0 - иначе это будет не True....
Размышляя в данном направлении можно прийти к мысли что просматривать логи на серверах (и прочих железяках) вещь конечно нужная, и часто много легче предупредить беду обнаружив, что на сервере начал сыпаться винт, чем придя на работу получать суть накала быстро соображая как теперь восстановить работоспособность груды железа и понять причины выхода его из строя. Но здесь мы натыкаемся на несколько неприятных моментов, потому что нужно каждый день тратить какое-то время что бы "зайти" на все важные сервера,
просмотреть логи, проанализировать ошибки, и так далее. Занятие монотонное и утомительное, и как правило на него ложат уже через неделю. Да, можно настроить сервер логов, на котором собирать логи со всех устройств. Но опять же, нужно кому то сидеть и смотреть эти логи - что в разрезе айтишника не имеет ничего общего. Исходя из таких вот негативных мыслей, Мы попытаемся сегодня настроить свой сервер централизованного хранения логов с блекджеком и шлюхами. И так подытожим, мы хотим что бы:
1. Сервер собирал логи на себя со всевозможных устройств (включая никрасофт)
2. Был бесплатен
3. Был гибок в настройке
4. Фильтровал сообщения
5. Мог отправлять админу почту с указанием источника и ошибки
6. Хранил логи в БД (мало ли, придет начальство а ты такой "ОППА" и хмуря брови смотришь лог....) --- ну вообще много для чего нужно на самом деле...
Итого, порывшись в тырнете и опробовав несколько вариантов сделал такие выводы:
Стандартный syslog - хорошо что везде есть, плохо что ограничен во всем.
syslog-ng (типа нью генерайшен) - уже много луче, но есть грабли с фильтрами и не поддерживает отправку писем из коробки.
Rsyslog - жуткий демон, может все что нужно, все в комплекте, но дурацкий синтаксис конфига и, к тому же, отличающийся в разных версиях !!! Эврика ! Это же то что нам нужно, и мозги размять и дело сделать и медаль на грудь себе потом повесить!!!
Итого, берем какое-то железяко или виртуалку, ставим на нее любую любимую вами *nix систему и принимаемся за настройку. Моей любимой системой в данный час оказалась
FreeBSD Logs 9.0-RELEASE-p4 (Logs - имя машинки)
Итак , предположим что у нас чистая, только что установленная система
установим необходимое из портов (на линуксе ставим своим методом):
# cd /usr/ports/sysutils/rsyslog6 && make install clean
# cd /usr/ports/sysutils/rsyslog6-mysql && make install clean
(обратите внимание я взял 6 версию, и мой конфиг на 5 работать не будет, на счет 7 не знаю)
# cd /usr/ports/databases/mysql55-server && make install clean
# cd /usr/ports/databases/mysql55-client && make install clean
Для начала вроде как хватит, теперь лезем в rc.conf и добавляем правила:
mysql_enable="YES"
syslogd_enable="NO"
rsyslogd_enable="YES"
rsyslogd_pidfile="/var/run/syslog.pid"
rsyslogd_flags="-c4"
Далее нам необходимо настроить rsyslog.conf - в мануале написанно что он у вас появится там-то и там-то, но у меня фокус не сработал и потому создаем его сами:
# touch /usr/local/etc/rsyslog.conf
Ниже я приведу свой конфиг, и постараюсь по максимуму его прокомментировать. В конфиге я старался затронуть основные моменты нужные нам для работы, хотя возможности самого rsyslog выходят далеко за рамки этой статьи и натворить в нем реально можно что угодно.
Некоторые моменты в конфиге вам будут не понятны, но по мере прочтения все станет на свои места...
Итак:
# cat /usr/local/etc/rsyslog.conf
#Модули которые нам нужны для работы необходимо явно указывать
#Добавим логирование локалхоста
$ModLoad imuxsock # provides support for local system logging
$ModLoad imklog # provides kernel logging support (previously done by rklogd)
# Модуль отвечающий за прослушку по UDP порту
$ModLoad imudp
# Порт сервера на котором слушать логгеров
$UDPServerRun 514
# Если не хотим что бы ломилось все в подряд, ограничим тех кто может ложить логи
$AllowedSender UDP, 127.0.0.1, 192.168.0.9, 192.168.0.141
#Поддержка БД MySQL (вобще ест поддержка и постгреса и т.д.)
$ModLoad ommysql#Настройки для отправки почты
$ModLoad ommail#smtp сервер
$ActionMailSMTPServer my.mail.server
#От кого будем получать логи
$ActionMailFrom report@my.mail.server
#Кому отправлять логи
$ActionMailTo report@my.mail.server
#Интересная штука темплейты. По сути что-то типа переменных но явно указанных.
#Напишем парочку темплейтов. с темой письма и содержимым для двух вариантов
#1 - для отправки сообщений с ошибками и 2 для отправки сообщений о ннедоступности хоста
#1
$template mailSubject,"ServerLog: Warning on %hostname%"
$template mailBody,"SERVERLOG\r\nError on %hostname%\r\nError = '%msg%'"
#2
$template mailBodyPing,"SERVERLOG\r\nThe %hostname% is DOWN"
#Нужно обьявить тему для почты.
$ActionMailSubject mailSubject
#Настройки вида отображения логов оставим по умолчанию, хотя вы можете сделать свои
$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
#Ну тут все понятно. Укажем кто хозяин логофайлов на сервере.
$FileOwner root
$FileGroup wheel
$FileCreateMode 0640
#Далее список правил для локалхоста, особо обьяснять не буду так как ето стандартные
#значения из сислога
# Log all kernel messages to the console.
kern.* /dev/console
# Log anything (except mail) of level info or higher.
*.info;mail.none;authpriv.none;cron.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/security# Log all the mail messages in one place.
mail.* -/var/log/maillog
# Log cron stuff
cron.* /var/log/cron# Everybody gets emergency messages
*.emerg *
# Save news errors of level crit and higher in a special file.
uucp,news.crit /var/log/spooler
# Save boot messages also to boot.log
local7.* /var/log/boot.log
#А вот теперь начинается магия...
#Создадим фильтры.
#Создадим фильтр, который следит за сообщениями в локальном сислоге, и
# если сообщение имеет в себе слово Alarm то выполняем действие, а именно
# отправляем ошибку в базу данных и отсылаем админу письмо!
# синтаксис почты понятен. А для базы данных (щас создадим) он такой
# :ommysql:servernamr,DB_name,username,password
# например у нас сервер локальный, имя базы = LogDB, пользователь = user, пароль =123
# тогда получим :ommysql:localhost,LogDB,user,123
#(Фильтрация по слову в сообщении $msg)
if $msg contains 'Alarm' then {
:ommail:;mailBodyPing :ommysql:localhost,LogDB,user,123
}
#Теперь добавим фильтр который например будет писать в БД все логи
#которые пришли к нам с айпишнека 10.0.0.10 (ну например это точка доступа)
#Filter to 10.0.0.10
if $hostname-ip == '10.0.0.10' then :ommysql:localhost,LogDB,user,123
# Но возможно вам не нужен весь хлам, тогда добавим условие на вторую точку доступа # с которой будем писать только логи с меткой ERROR
if ($hostname-ip == '10.0.0.10' and $msg contains 'ERROR') then ommysql:localhost,LogDB,user,123
#И пожалуй самый интересный фильр, ето парсить логи от нужного нам виндовго сервера,
# писать их а базу данных, но если сообщение сожерит ошибку - отправлять его на почту.
# По умолчанию у rsyslog есть замечательные фильтры. Воспользуемся ими
# (Очень рекомендую при создании фильтров юзать сей чудо мануал ТЫЦ-ТЫЦ)
#Зафильтруем по имени ПК и типу ошибки, что согласно мануала означает что отправлять на
# почту только логи попадающие в категорию
0 | KERN | Лог сообщения генерируемые ядром |
1 | USER | Лог сообщения генерируемые процессами пользователя |
2 | Лог сообщения от почтовой системы | |
3 | DAEMON | Лог сообщения генерируемые системными демонами |
if ($hostname == 'MOSTDIE' and $syslogseverity <= 3) then {
:ommail:;mailBody }
if ($hostname == 'MOSTDIE') then {
ommysql:localhost,LogDB,user,123
}
Для начала этого более чем достаточно! Сохраняем его !
И как и писалось раньше создадим базу данных и таблицы в ней (подразумевается что вы уже запустили Mysql и назначили пароль на рута)
mysql -u root -p yourpassword
mysql>
вводим
mysql> create database LogDB;
mysql> grant all privileges on LogDB.* to 'user'@'%' identified by '123' with grant option;
и создаем таблицы
mysql> use LogDB;
mysql>
DROP TABLE IF EXISTS `SystemEvents`;
CREATE TABLE `SystemEvents` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CustomerID` bigint(20) DEFAULT NULL,
`ReceivedAt` datetime DEFAULT NULL,
`DeviceReportedTime` datetime DEFAULT NULL,
`Facility` smallint(6) DEFAULT NULL,
`Priority` smallint(6) DEFAULT NULL,
`FromHost` varchar(60) DEFAULT NULL,
`Message` text,
`NTSeverity` int(11) DEFAULT NULL,
`Importance` int(11) DEFAULT NULL,
`EventSource` varchar(60) DEFAULT NULL,
`EventUser` varchar(60) DEFAULT NULL,
`EventCategory` int(11) DEFAULT NULL,
`EventID` int(11) DEFAULT NULL,
`EventBinaryData` text,
`MaxAvailable` int(11) DEFAULT NULL,
`CurrUsage` int(11) DEFAULT NULL,
`MinUsage` int(11) DEFAULT NULL,
`MaxUsage` int(11) DEFAULT NULL,
`InfoUnitID` int(11) DEFAULT NULL,
`SysLogTag` varchar(60) DEFAULT NULL,
`EventLogType` varchar(60) DEFAULT NULL,
`GenericFileName` varchar(60) DEFAULT NULL,
`SystemID` int(11) DEFAULT NULL,
`processid` varchar(60) NOT NULL DEFAULT '',
PRIMARY KEY (`ID`)
);
DROP TABLE IF EXISTS `SystemEventsProperties`;
CREATE TABLE `SystemEventsProperties` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`SystemEventID` int(11) DEFAULT NULL,
`ParamName` varchar(255) DEFAULT NULL,
`ParamValue` text,
PRIMARY KEY (`ID`)
);
Итог, конфиг настроен, база данных создана - перегружаемся и смотрим что получилось.
Если вы ничего не упустили и вдумчиво копировали конфиг, у Вас должен работать лог и rsyslog должен собирать данные с других ресурсов. Настройкой которых мы кстати сейчас и займемся.
Для того что бы наш мегаблекджек получал сообщения от серверов в сети, необходимо на этих самых серверах указать пересылать на него логи. Там где у вас установлен *nix проблем вообще никаких не возникает. Все штатно, стандартно и красиво и информации в гугле более достаточно. Но вот касаемо вопроса никрософта - пришлось таки опять читать много букав и подбирать варианты. Методом исключений был выбран победитель
Инструмент идеально прост, стабилен, удобен - но главное полностью удовлетворяет наши запросы, а именно:
1. Легко устанавливается
2. Имеет встроенный фильтр
3. Устанавливается как служба
4. Отправляет все логи Виндаусов на указанный сервер.
Итого качаем архив под свою платформу. Распаковываем и копируем из него два файла evtsys.dll и evtsys.exe в c:\windows\system32
Что Вам нужно знать о evtsys ? В целом можете посмотреть хелп и доступные опции. Но на данном этапе ограничимся следующим:
Установим его как службу и укажем куда хранить логи
cd c:\windows\evtsys.exe -i -h 192.168.0.1 (192.168.0.1 - айпи нашего лог сервера)
после чего перейдем в службы и запустим службу "Event to Syslog"
для проверки создадим батник с таким вот содержимым и выполним его:
EVENTCREATE /T ERROR /ID 100 /L SYSTEM /D "Oshibka type" /SO "CMD file"
EVENTCREATE /T WARNING /ID 111 /L SYSTEM /D "Atention type" /SO "Cmd File"
Получим в журнал ошибок два сообщения, одно со статусом еррор, второе варнинг !
(В конфиге вместо MOSTDIE укажите имя машинки на котрой установили evtsys и перезапустите rsyslog)
Смотрим журнал логов
# tail -f /var/log/messages
Если все сделано верно вы получите в сислог два сообщения, оба запишутся в базу данных, но на почту прийдет только одно письмо, с темой и содержанием ошибки.
Кстати, интересный вариант. Если вы не планируете писать логи в разные базы данных, или не хотите писать фильтры для всех виндомашин можно воспользоваться специальным фильтром
Facility - у которого на данный случай есть встроенные локальные переменные (Local0 -local7)
тогда правило в конфиге рсислога выглядело бы так (заюзаем local2)
local2.* ommysql:localhost,LogDB,user,123
а при установке evtsys укажем писать все свои логи в локальную переменную этого типа
evtsys.exe -i -f 18 -h 192.168.0.1 (-f 18 как раз наша переменная локал2 - читаем ман)
Ну вот в целом наша система и настроена. Уже можно пользоваться. Так же можно прикрутить к ней какую-то веморду типа loganalyzer и так далее которых в нете так же предостаточно (но я планирую написать свой, так что рассматривать в этой статье установку вебморды не буду). В целом - конфиг получился достаточно большой, и в нем много лишнего - но я постарался описать в нем все необходимые моменты нужные для работы. И очень жаль что я нигде не нашел столько манов в одном месте. Вся эта статья собрана по крупицам, а некоторые моменты пришлось выяснять методом подбора. По этому я надеюсь кому-то мой труд облегчит жизнь...
Итого, имеем свой блекджек со шлюхами как и хотели. Но девочки у нас не очень - надо бы их еще причесать для порядку. Мы же хотим что бы наш сервер, кроме всего прочего, опрашивал кучу айпишнеков в сети, и если чото не пингонулось - сообщать нам опять же на почту!!! Тут уже вы сами можете выбрать готовое решение или написать скрипт на шеле, но в я лично пошел таким путем:
Пишем скрипт который опрашивает ойпишнеки и если не пингеует выдает сообщение в сислог (А там у нас в засаде фиильтр который моментально реагирует и шлет письмо в начале конфига мы говорили об этом
#(Фильтрация по слову в сообщении $msg)
if $msg contains 'Alarm' then {
:ommail:;mailBodyPing :ommysql:localhost,LogDB,user,123
} )
Смешно звучит, но я за все время использования *nix систем так и не заставил себя выучить написание скриптов на баше, по сему предлагаю свой скрипт на pythone. В нем есть список айпишнеков которые нужно опрашивать, и в случае ошибки он дает месадж в сислог. Опять же - некоторые скажут а почему список айпишнеков в самом скрипте а не в отдельном файле который можно редактировать - отвечаю - потому что список составляется как правило один раз и весьма редко когда нужно его править, и ради етого добавлять усложнять скрипт чтением файла, и хранить его гдето я не вижу смысла. Если у вас есть такое желание допишите сами, даже не зная языка сделать это очень просто так как в официальных доках есть примеры. Итого сам скрипт (Внимание. Скрипт на питоне - пробелы и переносы сохранять):
# touch /usr/local/bin/checkiplist
# chmod +x /usr/local/bin/chekiplist
#cat /usr/local/bin/chekiplist
Ну и добавим красивый старт скрипта черег демон rc.d
# touch /usr/local/etc/rc.d/iplist.sh
# chmod +x /usr/local/etc/rc.d/iplist.sh
cat /usr/local/etc/rc.d/iplist.sh
iplist_enable="YES"
Ну вот и все! Теперь мы ленивые админы, все что остается - мониторить одним глазом почту
Удачи!
# touch /usr/local/bin/checkiplist
# chmod +x /usr/local/bin/chekiplist
#cat /usr/local/bin/chekiplist
#!/usr/local/bin/python
import subprocessimport time
import os
"""IP list tu ping"""
iplist = ['192.168.0.9', '192.168.0.141', '192.168.90.141']
"""Chek time. If time from 7 to 18 then chek every minute, else every hour"""
def checkTime():
cmdtime = int(time.strftime('%H'))
if (cmdtime >= 7 and cmdtime <= 18):
return time.sleep(60)
else:
return time.sleep(600)
def pingProcess(ip):
pingTest = "ping -c 1 " + ip process = subprocess.Popen( pingTest, shell=True, stdout=subprocess.PIPE)
process.wait()
returnCodeTotal = process.returncode if returnCodeTotal == 0:
pass else:
return os.system('logger "Alarm "' + ip + ' is Down')
def cykle():
for i in iplist:
pingProcess(i)
counter = 1
while counter == 1:
checkTime()
cykle()
Ну и добавим красивый старт скрипта черег демон rc.d
# touch /usr/local/etc/rc.d/iplist.sh
# chmod +x /usr/local/etc/rc.d/iplist.sh
cat /usr/local/etc/rc.d/iplist.sh
#!/bin/shи незабываем добавить в rc.conf строчку
#
# PROVIDE: iplist
# REQUIRE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subrname=iplist
command="/usr/local/bin/chekiplist &"
load_rc_config $name
iplist_enable=${iplist_enable-"NO"}
pidfile=${iplist_pidfile-"/var/run/iplist.pid"}
run_rc_command "$1"
iplist_enable="YES"
Ну вот и все! Теперь мы ленивые админы, все что остается - мониторить одним глазом почту
Удачи!