Возможно вы искали: 'Forza Motorsport 3'

May 15 2025 18:52:59
  • Как сделать 8Gamers.Ru домашней страницей?
  • Игры
    • База данных по играх
    • Игровые новости
    • Игровая индустрия
    • Обзоры на игры
    • Прохождения игр
    • Гайды к играм
    • Превью о играх
    • Игровые тизеры
    • Игровые арты
    • Игровые обои
    • Игровые скриншоты
    • Игровые обложки
    • Игровые трейлеры
    • Игровое видео
    • Вышедшие игры
    • Ближайшие релизы игр
  • Кино и ТВ
    • База данных по кино
    • Статьи о кино
    • Постеры
    • Кадры из кино
    • Кино трейлеры
    • Сегодня в кино
    • Скоро в кино
  • Комиксы и манга
    • Манга по алфавиту
    • База данных по комиксах
    • Читать онлайн комиксы
    • Читать онлайн манга
    • База персонажей
  • Читы и коды
    • Чит-коды для PC игр
    • Чит-коды для консольных игр
    • Трейнеры
    • Коды Game Genie
  • Моддинг
    • Модификации
    • Карты к играм
    • Программы для моддинга
    • Статьи о моддинге
  • Геймдев
    • Всё о создании игр
    • Список движков
    • Утилиты в помощь игроделу
    • Конструкторы игр
    • Игровые движки
    • Библиотеки разработки
    • 3D-модели
    • Спрайты и тайлы
    • Музыка и звуки
    • Текстуры и фоны
  • Рецензии
    • Игры
    • Кино
    • Аниме
    • Комиксы
    • Мангу
    • Саундтреки
  • Саундтреки
    • Лирика
  • Файлы
    • Патчи к играм
    • Русификаторы к играм
    • Сохранения к играм
    • Субтитры к кино
  • Медиа
    • Видео
    • Фото
    • Аудио
    • Фан-арты
    • Косплей
    • Фото с виставок
    • Девушки из игр
    • Рисунки
    • Рисуем онлайн
    • Фотохостинг
  • Юмор
    • Анекдоты
    • Афоризмы
    • Истории
    • Стишки и эпиграммы
    • Тосты
    • Цитаты
  • Флеш
    • Азартные
    • Аркады
    • Бродилки
    • Гонки
    • Для девочек
    • Для мальчиков
    • Драки
    • Квесты
    • Леталки
    • Логические
    • Мультфильмы
    • Открытки
    • Приколы
    • Разное
    • Спорт
    • Стратегии
    • Стрелялки
Статистика

Статей: 87772
Просмотров: 96111483
Игры
Injustice:  Gods Among Us
Injustice: Gods Among Us
...
Dark Souls 2
Dark Souls 2
Dark Souls II - вторая часть самой хардкорной ролевой игры 2011-2012 года, с новым героем, сюжето...
Battlefield 4
Battlefield 4
Battlefield 4 - продолжение венценосного мультиплеер-ориентированного шутера от первого ли...
Кино
Steins;Gate
Steins;Gate
Любители японской анимации уже давно поняли ,что аниме сериалы могут дать порой гораздо больше пи...
Ку! Кин-дза-дза
Ку! Кин-дза-дза
Начинающий диджей Толик и всемирно известный виолончелист Владимир Чижов встречают на шумной моск...
Обзоры на игры
• Обзор Ibara [PCB/PS2] 18357
• Обзор The Walking ... 18801
• Обзор DMC: Devil M... 19879
• Обзор на игру Valk... 15877
• Обзор на игру Stars! 17764
• Обзор на Far Cry 3 17948
• Обзор на Resident ... 16024
• Обзор на Chivalry:... 17508
• Обзор на игру Kerb... 17981
• Обзор игры 007: Fr... 16619
Превью о играх
• Превью к игре Comp... 17960
• Превью о игре Mage... 14464
• Превью Incredible ... 14721
• Превью Firefall 13479
• Превью Dead Space 3 16334
• Превью о игре SimC... 14730
• Превью к игре Fuse 15442
• Превью Red Orche... 15542
• Превью Gothic 3 16343
• Превью Black & W... 17354
Главная » Статьи » Разное » Разработка скрипта для протоколирования событий и мониторинга MySQL и Apache (monitor shell log apache web mysql)

Разработка скрипта для протоколирования событий и мониторинга MySQL и Apache (monitor shell log apache web mysql)

Ключевые слова: monitor, shell, log, apache, web, mysql, (найти похожие документы)

From: Foxy S. Aries (Alexei A. Abramov) <foxy@randconsult.ru.>
Newsgroups: http://www.freelance.pp.ru
Date: Mon, 20 Sep 2004 18:21:07 +0000 (UTC)
Subject: Разработка скрипта для протоколирования событий и мониторинга MySQL и Apache

Оригинал: http://www.freelance.pp.ru

Скрипт протоколирования событий на shell.

Содержание:
* Зачем это нужно;
* Формулируем основные требования;
* Интерфейс и расположение;
* Переменные скрипта;
* Отправка e-mail;
* Запись в файл протокола и его ротация;
* Что получилось;
* Просмотр записей в браузере;
* Заключение.

Зачем это нужно


Предположим, что у нас есть UNIX-box или целая ферма серверов,
возможно, есть набор сервисов у хостинг-провайдера или удаленные
серверы. Время от времени состояние серверов и демонов изменяется:
свободное пространство какого-либо раздела может исчерпаться, вслед за
этим тихо <<валится>> squid, может <<упасть>> web-сервер или
отключиться репликация баз данных. Предположим, что наступление всех
критических событий контролируется. Неважно, какими средствами, хотя
бы и скриптами из cron. Возникает вопрос: как оперативно оповестить
системного администратора о том или ином событии, не заставляя его
денно и нощно читать логи?


Формулируем основные требования

Некоторого представления о скриптинге на shell и настроенного MTA
(sendmail) оказывается вполне достаточно, чтобы разработать несложную
и вместе с тем надежную и гибкую систему протоколирования. Итак,
исходные требования к ней:

* простота и гибкость - по-моему, проще shell нет ничего и,
вооружившись руководствами, можно легко добавить скрипту
дополнительные возможности или же заставить его работать
по-другому;
* оперативность оповещения - система будет отправлять почтовые
сообщения на e-mail системного администратора;
* надежность - дополнительный протокол, в который не только
дублируются сами критические события, но и результаты отправки
почтовых сообщений;
* безопасность - дело сисадмина закрывать <<дыры>>, но никак не
обратное;
* бережное отношение к дисковому пространству - весьма неплохо
хранить протоколы как можно дольше, чтобы при этом они <<весили>>
как можно меньше.


Интерфейс и расположение

Сначала определим местоположение скрипта и директории протоколов нашей
системы. На мой взгляд, резонно создать
/root/scripts/ с режимом 500 (r-x) и владельцем root:wheel и
расположить скрипт там с такими же правами, назовем его
report.error.sh. К тому же, наверняка, контроль событий ведется от
имени rootа и у вызывающих программ хватит прав вызывать скрипт.
Протоколы будут находиться в /var/log/ и называться error.reports.log.
Такое расположение оптимально, по сравнению, например, с /usr/local/,
особенно, если в операционной системе есть аккаунты "живых"
пользователей.

Положим порядок и значение передаваемых скрипту report.error.sh
параметров:

1. имя вызывающей программы;
2. процедура или проверяемое событие;
3. код ошибки или завершения (иногда здорово помогает);
4. поток вывода и/или ошибок вызывающей программы.


Переменные скрипта

Начнем c инициализации переменных. Иногда, удобно определить даже то,
что только гипотетически может измениться как переменную и вынести ее
наверх. Удобство проявляется в громоздком скрипте, который до этого
был забыт на год-два:

#!/bin/sh

recipient=admin@host.ru
ccrecipient=admin_ cell_phone@nwgsm.ru
log_file=/var/log/error.reports.log
max_log_file_size=500000 # in bytes
date=`date`


Получатель email в recipient, копия направляется ccrecipient,
<<собака>> в адресах обязательно экранируется "". Из соображений
повышения надежности доставки, хост у recipient лучше выбрать с
наименьшей вероятностью того, что он будет недоступен.
Сверхоперативное оповещение можно организовать элементарно,
зарегистрировав почтовый ящик у оператора сотовой связи и отправляя
копии на него. У <<Мегафона>> такая услуга есть, доставка практически
моментальная. Имя файла протокола - log_file, max_log_file_size -
максимальный размер в байтах, при достижении которого будет
производиться ротация. В переменную date заносится текущее время и
дата в формате и локали rootа:

Tue Oct 14 15:31:16 MSD 2003


Отправка e-mail

Первым делом, пытаемся отправить почтовое сообщение:

mail -s "Сообщение об ошибке" -c $ccrecipient $recipient <<!
Время: $date
Скрипт: $1
Действие: $2
Дополнительная информация:
Код ошибки: $3
Поток вывода ошибочной команды:
$4
!


Для единственного получателя вызов mail немного иной:

mail -s "Сообщение об ошибке" $recipient <<!


Если основным почтовым клиентом будет сотовый телефон администратора,
темой сообщения стоит сделать второй передаваемый параметр, чтобы без
дополнительных манипуляций (открытия тела сообщения) и расходов
получить представление о произошедшем.

По коду возврата mail проверяем, ушла ли почта. В условном операторе
можно расположить и другой полезный код, например, реанимирующий
sendmail:

if [ $? -ne 0 ]
then not_string=" не"
fi


Запись в файл протокола и его ротация

Затем, записываем переданные параметры и отчет отправки в наш
лог-файл. Разделителями полей могут служить любые символы, не только
табуляции. Все зависит от того, кто будет читать протоколы: человек,
парсер или все понемногу. По моему мнению, для последней ситуации,
один символ табуляции как разделитель полей - компромисс: MS Excel
будет счастлив при импорте, с текстовой консоли лог вполне читаем и
парсер на Perl написать несложно:

echo "$date $1 $2 $3 $4
Уведомление $not_string отправлено ${recipient},
копия ${ccrecipient}." >> $log_file


Немного белой магии. Если размер файла протокола стал больше
max_log_file_size, его нужно ротировать, а ротированный - сжать.

Выясняем размер протокола в байтах и сравниваем с предельным:

log_file_size=`wc -c $log_file | awk '{print $1}'`
if [ $log_file_size -gt $max_log_file_size ]


При положительном результате, проверяем наличие в /var/log/ файлов
error.reports.log.0.gz, потом error.reports.log.1.gz,
error.reports.log.2.gz и так далее. Это суть ротированные и сжатые до
этого логи. Последовательный перебор идет до тех пор, пока не найдется
последний файл или <<окно>> между ними (очевидно, что заглядывать в
/var/log/ нужно чаще, чем i станет больше MAXINT):

then
i=0
while [ -f $log_file.$i.gz ]
do
i=`expr $i + 1`
done


Ротируем, сжимаем и оставляем запись об этом в следующем протоколе:

mv $log_file $log_file.$i
gzip $log_file.$i
echo "`date`: Ротация логов.
Предыдущий сохранен с номером $i" >> $log_file
fi


Что получилось

Скрипт целиком выглядит так:

#!/bin/sh

recipient=admin@host.ru
ccrecipient=admin_ cell_phone@nwgsm.ru
log_file=/var/log/error.reports.log
max_log_file_size=500000 # in bytes
date=`date`

### send mail ###
mail -s "Сообщение об ошибке" -c $ccrecipient $recipient <<!
Время: $date
Скрипт: $1
Действие: $2
Дополнительная информация:
Код ошибки: $3
Поток вывода ошибочной команды:
$4
!

### test if mail is sent ###
if [ $? -ne 0 ]
then not_string=" не"
fi

### log into file ###
echo "$date $1 $2 $3 $4
Уведомление $not_string отправлено ${recipient},
копия ${ccrecipient}." >> $log_file

### turn over log file if needed ###
log_file_size=`wc -c $log_file | awk '{print $1}'`
if [ $log_file_size -gt $max_log_file_size ]
then
i=0
while [ -f $log_file.$i.gz ]
do
i=`expr $i + 1`
done
mv $log_file $log_file.$i
gzip $log_file.$i
echo "`date`: Ротация логов.
Предыдущий сохранен с номером $i" >> $log_file
fi


Теперь его можно вызывать из других скриптов или программ мониторинга.
Вызов из скрипта /root/scripts/monitor.something.sh, запущенного от
имени rootа делается примерно так:

#!/bin/sh
...
some_parameters="process"
...
result=`/usr/local/bin/some_program -$some_parameters 2>&1`
result_code=$?
if [ $result_code -ne 0 ]
then
/root/scripts/report.error.sh $0 "нет ответа
от $some_parameters в течение 1 сек." $result_code "$result"
fi
...


В качестве уведомления на адреса admin@host.ru и admin_
cell_phone@nwgsm.ru приходит письмо:

From: Charlie Root
To: admin@host.ru
Subject: Сообщение об ошибке


Время: Tue Oct 14 15:31:16 MSD 2003
Скрипт: /root/scripts/monitor.something.sh
Действие: Нет ответа от process в течение 1 сек.
Дополнительная информация:
Код ошибки: 1
Поток вывода ошибочной команды:
Can't connect to server (Operation timed out)


Просмотр записей в браузере

Можно пойти дальше - дополнить нашу систему протоколирования несложным
парсером для просмотра протоколов с помощью браузера. Для этого
подойдет web-сервер apache, у которого есть настроенная на
аутентифицированный доступ (<<закрытая паролем>>, как говорят в
народе) директория cgi-bin. Вот [30]вполне работоспособный пример
скрипта парсера на Perl, который помещается в эту самую директорию с
режимом 500 (r-x) и владельцем www:www (или тем, который прописан в
конфигурации web-сервера):

#!/usr/bin/perl

my $logfile="/var/log/error.reports.log";

print "Content-type:text/htmlnn";
print "<html><title> Статистика ошибок</title>n";
print "<table border=1>n";
print "<td>дата</td><td>время</td><td>скрипт</td>
<td>действие/описание ошибки</td><td>код ошибки</td>
<td>поток вывода</td><td>получатель уведомления</td>n";

open(LOGHANDLE,"<$logfile");
flock(LOGHANDLE,2);
readline(*LOGHANDLE);
while(my $stat_line=readline(*LOGHANDLE))
{
my @stat_strings=split(/t/,$stat_line);
if ($stat_strings[0]=~s/(dd:dd:dd)//)
{
print "</td><tr><td>$stat_strings[0]</td>n";
print "<td>$1</td>n";
print "<td>$stat_strings[1]</td>n";
print "<td>$stat_strings[2]</td>n";
print "<td>$stat_strings[3]</td>n";
print "<td>$stat_strings[4]n";
}
else
{
print "$stat_line
n";
}
if ($stat_line=~/Уведомлениеs+отправленоs+(S+)./)
{
print "</td><td>$1</td>n";
}

}
flock(LOGHANDLE,8);
close(LOGHANDLE);
print "</td></table>n";
print "</body></html>n";

exit 0;


Нетрудно заметить, что скрипт справляется с потоком вывода, содержащим
несколько строк, но совершенно не приспособлен для просмотра архивов
gzip. Частично эта проблема решается, если сначала ротировать протокол
в самом начале, до отправки почтовых сообщений, тогда лог будет
содержать, как минимум, запись о последнем событии.


Заключение

Основная цель данной статьи заключается в том, чтобы создать фундамент
для размышлений и дальнейшего развития и совершенствования скрипта,
поделиться накопленным опытом, но никак не дать готовые решения для
бездумного, слепого копирования или же научить принципам
программирования. Как говаривал агент Малдер о своем автомобиле:
<<Руль где-то рядом>>.



Скрипт мониторинга web-сервера

Содержание:
* Жизненные ситуации;
* Формулируем основные требования;
* Расположение скрипта и взаимодействие с другим ПО;
* Приступаем к разработке;
* Собираем все вместе;
* Запуск скрипта из cron;
* Подведение итогов;
* Заключение.


Жизненные ситуации


Иногда требуется уверенность в том, что web-сервер доступен для
клиентов. Конфигурации web-серверов могут быть очень и очень разные,
да и всегда есть место человеческому фактору - все мы время от времени
ошибаемся, забываем что-то. В моей практике частенько встречаются
подобные вещи, особенно это касается виртуального хостинга и
программирования динамических сайтов - отладили на локальном сервере,
<<залили>> к хостинг-провайдеру - не работает. Другая ситуация:
старались люди, программировали - обновил администратор
хостинг-провайдера версию PHP, а в ней какая-то команда или код ее
возврата поменялся; результат - сайт <<лег>>.

В общем, ситуаций, когда нужно периодически проверять
работоспособность web-сервера, много, и в этой статье автор поделился
опытом в решении этой проблемы. Возможно, кому-то проще решить
проблему <<в лоб>> - ps ax | grep httpd для локального хоста или
специально нанять сотрудника и усадить его за Internet Explorer.


Формулируем основные требования


Дабы не изобретать велосипед (хотя бы в этот раз), скрипт мониторинга
будет пользоваться для оповещения и протоколирования другим скриптом
/root/scripts/report.error.sh, разработка которого детально описана в
статье <<Скрипт протоколирования событий на shell>>. Итак,
сформулируем требования к скрипту мониторинга:

* простота - язык скриптинга shell;
* генерация минимального трафика - платить за лишний трафик ни к
чему;
* надежность оповещения - скрипт будет вызывать протоколирующий и
отсылающий сообщение на e-mail скрипт;
* оперативность оповещения - разумный компромисс между объемом
генерируемого трафика и частотой запуска скрипта из cron;
* безопасность - куда ж без нее;
* возможность модернизации - допустим, в будущем неплохо было бы
вести статистику времени ответа сервера.



Расположение скрипта и взаимодействие с другим ПО

Определим местоположение скрипта. Доводы в пользу /root/scripts/ с
режимом 500 (r-x) и владельцем root:wheel приведены в статье
<<Скрипт протоколирования событий на shell>>, поэтому не буду
повторяться. Скрипт мониторинга, назовем его monitor.websites.sh,
будет иметь режим 500 (r-x) и владельца root:wheel. Этим
обеспечиваются требования информационной безопасности.

В принципе, можно ограничиться банальным запуском telnet по 80-му
порту. Есть более интересный, к тому же отвечающий требованиям
расширяемости, вариант - малюсенькая, но очень функциональная
программа echoping, разработанная Stephane Bortzmeyer
(bortz@users.sourceforge.net, bortzmeyer@nic.fr). В коллекции
портов FreeBSD она находится в /usr/ports/net/echoping, в исходниках
ее можно взять с ftp://ftp.internatif.org/pub/unix/echoping . Кроме
очень толкового man и readme, есть страничка echoping на
http://echoping.sourceforge.net/. Размеры архива небольшие, поэтому
взять исходники или инсталлировать echoping из портов вполне реально,
даже с медленным модемом.

Инсталляция echoping из портов (две команды с консоли - вот в чем вся
прелесть портов):

server# cd /usr/ports/net/echoping
server# make install


Инсталляция из исходников чуть сложнее:

server# tar -xzf echoping-5.1.0.tar.gz
server# cd echoping-5.1.0
server# ./configure
server# make
server# make install


Советую почитать документацию и посетить [34]домашнюю страничку
echoping, оттуда можно почерпнуть много весьма полезного не только по
теме, но и для общего развития, так сказать - областей применения для
этой программы не счесть.


Приступаем к разработке

Функции скрипта мониторинга сводятся к вызову echoping, обработке
информации по завершению и вызову скрипта протоколирования, если
что-то не в порядке. Тестироваться будет хост http://remote.host.ru:

#!/bin/sh

ping_host="remote.host.ru"


Следующий этап - решить, что же именно нужно тестировать: доступность
хоста вообще или же доступность определенного URL. Чтобы тестировать
доступность хоста создадим небольшой текстовый файл
echoping.answer.txt, с произвольным содержанием. Размещение его на
web-сервере роли не играет, лишь бы echoping смог его открывать (это
легко проверить с помощью браузера). Файл такого содержания имеет
размер всего 44 байта:

This is the sample answer file for echoping.


По логике вещей, доступность хоста - есть доступность URL, например,
index.html на нем. В чем разница? В том, что порядок размера того же
index.html - десятки килобайт, а echoping.answer.txt - десятки байт.
Получается немалый выигрыш в трафике: если требуется знать всего лишь
доступность хоста, незачем брать большой файл:

ping_file="/echoping.answer.txt"


Чтобы протестировать доступность страницы, переменной ping_file просто
присваивается соответствующее значение:

ping_file="/some_dir/some-page.html"


Вызов echoping с сохранением кода завершения и потока вывода будет
выглядеть так:

result=`/usr/local/bin/echoping -h $ping_file $ping_host 2>&1`
result_code=$?


У некоторых хостинг-провайдеров виртуальные хосты сконфигурированы
так, что echoping может работать только со следующей командной
строкой:

result=`/usr/local/bin/echoping -h http://${ping_host}${ping_file}
$ping_host 2>&1`


По документации, код возврата не нулевой, если что-то не в порядке.
Следующий фрагмент кода запускает в этом случае скрипт
/root/scripts/report.error.sh, который отсылает уведомление с
подробностями (потоком вывода echoping) по e-mail и оставляет запись в
протоколе:

if [ $result_code -ne 0 ]
then
/root/scripts/report.error.sh $0 "
Нет ответа от $ping_host в течение 1 сек." $result_code "$result"
fi


Собираем все вместе

Привожу этот простой [36]скрипт целиком:

#!/bin/sh

ping_host="remote.host.ru"
ping_file="/echoping.answer.txt"

result=`/usr/local/bin/echoping -h $ping_file $ping_host 2>&1`
result_code=$?
if [ $result_code -ne 0 ]
then
/root/scripts/report.error.sh $0 "
Нет ответа от $ping_host в течение 1 сек." $result_code "$result"
fi


Запуск скрипта из cron

Осталось только сконфигурировать cron, чтобы скрипт действительно
занимался мониторингом. Существует одна тонкость: в частоте запуска
скрипта следует соблюсти баланс между объемами трафика (не стоит
ориентироваться на размеры echoping.answer.txt, HTTP-сессия сама по
себе генерирует трафик) и достоверностью информации (вероятность того,
что хост может быть недоступен, увеличивается со временем после
очередного запуска echoping).

Задания, выполняемые от имени root перечисляются в
/var/cron/tabs/root. Если его нет, можно создать файл в текстовом
редакторе или доверить создание непосредственно самому crontab:

server# crontab -e -u root


Строка, конфигурирующая cron для запуска
/root/scripts/monitor.websites.sh каждые 30 минут:

*/30 * * * * /root/scripts/monitor.websites.sh


Советую проследить режим файла заданий - 600 (rw-) с владельцем
root:wheel и наличие в нем переменных окружения:

SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
HOME=/var/log


После внесения изменений нужно, чтобы cron перечитал список заданий:

server# crontab -u root /var/cron/tabs/root


В /var/log/cron появится запись:

Mar 30 11:11:11 server crontab[75680] REPLACE (root)


Подведение итогов

Все. С этого момента в своих протоколах /root/scripts/report.error.sh
будет писать:

Tue Mar 30 11:11:11 MSD 2004
/root/scripts/monitor.websites.sh
нет ответа от remote.host.ru в течение 1 сек. 1
Can't connect to server (Operation timed out)
Уведомление отправлено admin@host.ru,
копия admin_cell_phone@nwgsm.ru


А на e-mail, указанные в скрипте будут приходить письма:

Date: Tue, 30 Mar 2003 11:11:11 +0300 (MSK)
From: Charlie Root <root>
To: admin@ host.ru
Subject: Сообщение об ошибке


Время: Tue Mar 30 11:11:11 MSD 2004
Скрипт: /root/scripts/monitor.websites.sh
Действие: нет ответа от remote.host.ru в течение 1 сек.
Дополнительная информация:
Код ошибки: 1
Поток вывода ошибочной команды:
Can't connect to server (Operation timed out)

Например, такое письмо будет свидетельствовать о том, что на
компьютере, где работает echoping проблемы с DNS:

Date: Tue, 30 Mar 2003 11:11:11 +0300 (MSK)
From: Charlie Root <root>
To: admin@host.ru
Subject: Сообщение об ошибке


Время: Tue Mar 30 11:11:11 MSD 2004
Скрипт: /root/scripts/monitor.websites.sh
Действие: нет ответа от remote.host.ru в течение 1 сек.
Дополнительная информация:
Код ошибки: 1
Поток вывода ошибочной команды:
getaddrinfo error for host: remote.host.ru
No address associated with hostname

Изучив документацию к echoping, нетрудно заметить, что скрипт
мониторинга может дополниться <<фичей>> мониторинга прокси-сервера, а
применив awk можно вести статистику среднего времени отклика
web-сервера. По-моему, звучит заманчиво. Кто-то, наоборот посчитает
статью ерундой - отлично, те же самые функции реализуются скриптом на
Perl socket-программированием, правда, по-любому, такой скрипт будет
гораздо более объемным.


Заключение

Повторюсь, что целью данной статьи, как и других, впрочем, не было
написание краткого руководства по программированию на shell. Было
время - была конкретная проблема, но не было опыта ее решения.
Проблема решена - появился опыт, значит, нужно им поделиться, дабы
другие на те же грабли не наступали. В любом случае, буду признателен
за конструктивную критику.



Скрипт мониторинга репликации MySQL на shell

Содержание:
* А в ответ - тишина...;
* Основные требования и возможности;
* Местоположение скрипта и аккаунт мониторинга;
* Разработка скрипта. Проблема первая;
* Разработка скрипта. Проблема вторая;
* Доводим до совершенства;
* Собираем все вместе;
* Запуск скрипта из cron;
* Подведение итогов;
* Заключение.


А в ответ - тишина...

Поступив на работу в организацию, где тружусь на чье-то благо и по сей
день, постепенно стало обнаруживаться, что хоть UNIX и беспрецедентно
надежная операционная система, а приложения для нее все же могут
давать сбои. Тогда и пришлось разрабатывать целую систему скриптов
контроля за состоянием целого ряда демонов. Отдел программирования в
то время занимался девелопингом весьма запутанной автоматизированной
информационной системы средствами PHP и MySQL. Средством синхронизации
была выбрана репликация баз данных того самого MySQL. Хорошо это или
плохо - не время и не место обсуждать, но жить с этим приходится, и
будет приходиться еще долго.

Основная проблема состоит в том, что при обнаружении несоответствия
или невозможности выполнить INSERT статус репликации тихо меняется на
<<OFF>>. Обнаружить причину удается не сразу, учитывая сложность
окружения (Apache, DNS, GD) и наличие <<глюков>> в скриптах PHP на
этапе разработки.


Основные требования и возможности

Как и рассмотренный в статье <<Скрипт мониторинга web-сервера на
shell>>, скрипт мониторинга репликации будет пользоваться для
оповещения и протоколирования другим скриптом
/root/scripts/report.error.sh, разработка которого детально описана в
статье [31]<<Скрипт протоколирования событий на shell>>.

Итак, сформулируем требования к скрипту мониторинга:

* простота - язык скриптинга shell;
* генерация минимального трафика - платить за лишний трафик ни к
чему;
* надежность оповещения - скрипт будет вызывать протоколирующий и
отсылающий сообщение на e-mail скрипт;
* оперативность оповещения - разумный компромисс между объемом
генерируемого трафика и частотой запуска скрипта из cron;
* полнота оповещения - скрипт должен оповещать не только об
остановке репликации, но и о факте <<падения>> сервера;
* безопасность - MySQL очень уязвим в связках и сам по себе;
* возможность модернизации - в будущем возможна смена
хостинг-провайдера, адресов или портов серверов.



Местоположение скрипта и аккаунт мониторинга

Определим местоположение скрипта. Доводы в пользу /root/scripts/ с
режимом 500 (r-x) и владельцем root:wheel приведены в статье
<<Скрипт протоколирования событий на shell>>, поэтому не буду
повторяться. Скрипт мониторинга, назовем его monitor.mysql.sh, будет
иметь режим 500 (r-x) и владельца root:wheel. Этим обеспечиваются
требования информационной безопасности на уровне операционной системы.
В составе MySQL поставляется широко известная пакетная утилита
mysqladmin, которая и будет источником информации для скрипта.
Соответственно, чтобы подсоединиться к серверу, необходим аккаунт
пользователя. Для целей мониторинга вполне подойдет пользователь,
назовем его repcontrol, с единственным правом USAGE, причем без права
его передачи и длинным паролем. Резонным будет ограничить возможность
соединения по хостам, если нет веских причин на обратное - мониторинг
ведется только с одного хоста. Этим мы удовлетворим требования
информационной безопасности по отношению к MySQL. На каждом
контролируемом сервере от имени rootа отдадим:

GRANT USAGE ON *.* TO 'repcontrol'@'host.ru' IDENTIFIED BY 'guessable';


Подробнее с добавлением аккаунтов пользователей MySQL можно
ознакомиться на странице [36]5.5.3 Adding New User Accounts to MySQL.

Теперь можно взглянуть на перечень параметров MySQL-сервера, которые
поддаются мониторингу:

server# mysqladmin -hhost.ru -P3306 -urepcontrol -pguessable extended-status
+--------------------------+--------+
| Variable_name | Value |
+--------------------------+--------+
| Aborted_clients | 0 |
| Aborted_connects | 0 |
| Bytes_received | 15949 |
| Bytes_sent | 414411 |
| Com_admin_commands | 63 |
| Com_alter_table | 0 |
| Com_analyze | 0 |
| Com_backup_table | 0 |
| Com_begin | 0 |
| Com_change_db | 2 |
| Com_change_master | 0 |
| Com_check | 0 |
| Com_commit | 0 |
| Com_create_db | 0 |
| Com_create_function | 0 |
| Com_create_index | 0 |
| Com_create_table | 0 |
| Com_delete | 0 |
| Com_drop_db | 0 |
| Com_drop_function | 0 |
| Com_drop_index | 0 |
| Com_drop_table | 0 |
| Com_flush | 0 |
| Com_grant | 0 |
| Com_insert | 0 |
| Com_insert_select | 0 |
| Com_kill | 0 |
| Com_load | 0 |
| Com_load_master_table | 0 |
| Com_lock_tables | 0 |
| Com_optimize | 0 |
| Com_purge | 0 |
| Com_rename_table | 0 |
| Com_repair | 0 |
| Com_replace | 0 |
| Com_replace_select | 0 |
| Com_reset | 0 |
| Com_restore_table | 0 |
| Com_revoke | 0 |
| Com_rollback | 0 |
| Com_select | 46 |
| Com_set_option | 46 |
| Com_show_binlogs | 0 |
| Com_show_create | 46 |
| Com_show_databases | 0 |
| Com_show_fields | 46 |
| Com_show_grants | 0 |
| Com_show_keys | 0 |
| Com_show_logs | 0 |
| Com_show_master_status | 0 |
| Com_show_open_tables | 0 |
| Com_show_processlist | 0 |
| Com_show_slave_status | 0 |
| Com_show_status | 34 |
| Com_show_innodb_status | 0 |
| Com_show_tables | 2 |
| Com_show_variables | 0 |
| Com_slave_start | 0 |
| Com_slave_stop | 0 |
| Com_truncate | 0 |
| Com_unlock_tables | 0 |
| Com_update | 0 |
| Connections | 101 |
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 0 |
| Created_tmp_files | 0 |
| Delayed_insert_threads | 0 |
| Delayed_writes | 0 |
| Delayed_errors | 0 |
| Flush_commands | 1 |
| Handler_delete | 0 |
| Handler_read_first | 8 |
| Handler_read_key | 0 |
| Handler_read_next | 0 |
| Handler_read_prev | 0 |
| Handler_read_rnd | 0 |
| Handler_read_rnd_next | 4520 |
| Handler_update | 0 |
| Handler_write | 0 |
| Key_blocks_used | 0 |
| Key_read_requests | 0 |
| Key_reads | 0 |
| Key_write_requests | 0 |
| Key_writes | 0 |
| Max_used_connections | 1 |
| Not_flushed_key_blocks | 0 |
| Not_flushed_delayed_rows | 0 |
| Open_tables | 46 |
| Open_files | 97 |
| Open_streams | 0 |
| Opened_tables | 52 |
| Questions | 320 |
| Select_full_join | 0 |
| Select_full_range_join | 0 |
| Select_range | 0 |
| Select_range_check | 0 |
| Select_scan | 39 |
| Slave_running | ON |
| Slave_open_temp_tables | 0 |
| Slow_launch_threads | 0 |
| Slow_queries | 0 |
| Sort_merge_passes | 0 |
| Sort_range | 0 |
| Sort_rows | 0 |
| Sort_scan | 0 |
| Table_locks_immediate | 51 |
| Table_locks_waited | 0 |
| Threads_cached | 0 |
| Threads_created | 99 |
| Threads_connected | 2 |
| Threads_running | 2 |
| Uptime | 228103 |
+--------------------------+--------+


Первой переменной скрипта и будут реквизиты созданного аккаунта:

mysql_user="-urepcontrol -pguessable"


Разработка скрипта. Проблема первая

В разработке скрипта мониторинга серверов MySQL есть две проблемы, по
сути, решение которых и будет составлять код скрипта: первая -
получить часть строки из таблицы напротив параметра Slave_running,
вторая - серверов может быть несколько, и работать они могут на разных
хостах и портах - избежать путаницы.
Первая проблема весьма просто решается применением awk и grep. Сначала
утилита mysqladmin соединяется с сервером и получает расширенную
таблицу статусов, ее листинг приведен в конце предыдущего раздела:

server# mysqladmin -hhost.ru -P3306 -urepcontrol -pguessable
extended-status 2>&1


Затем из потока вывода с помощью grep можно получить интересующую
строку:

server# mysqladmin -hhost.ru -P3306 -urepcontrol -pguessable
extended-status 2>&1 | grep Slave_running
| Slave_running | ON |


По умолчанию awk считает разделителями полей пробельные символы,
следовательно, статус репликации - четвертый столбец:

server# mysqladmin -hhost.ru -P3306 -urepcontrol -pguessable
extended-status 2>&1 | grep Slave_running | awk '{print $4}'
ON


Так как поток диагностических сообщений перенаправляется в стандартный
поток вывода, в случае возникновения каких-либо проблем, например,
отсутствия связи с сервером, переменная result будет пустой. Условная
конструкция будет выглядеть примерно так:

result=`mysqladmin -hhost.ru -P3306 -urepcontrol -pguessable
extended-status 2>&1 | grep Slave_running | awk '{print $4}'`
case $result in
ON) ;;
OFF) /root/scripts/report.error.sh $0
"репликация на host.ru:3306 отключена" 0 "пусто";;
*) /root/scripts/report.error.sh $0 "невозможно
получить статус репликации на host.ru:3306 0 "пусто";;
esac


Недостаток подобной конструкции состоит в невозможности диагностики
конкретной причины пустого (или отличного от <<ON>> и <<OFF>>) result.
Существенным он может быть только в случае неустойчивого модемного
соединения по плохому каналу в цепочке между хостом мониторинга и
контролируемым хостом. По логике вещей, в любом другом случае,
невозможность получить статус репликации говорит о том, что сервер
<<лег>>.


Разработка скрипта. Проблема вторая

Если серверов MySQL несколько, а такая ситуация не так уж редка, то
скрипт превращается в запутанную последовательность строк с result и
case. Причем, чем больше серверов нуждаются в контроле, тем больше
вероятность допустить где-нибудь ошибку. Выход напрашивается сам собой
- использовать цикл. Но как быть, если на одном хосте сервера работают
на одних портах, а на другом - на совершенно отличных, и найти
какую-то закономерность сложно? Оригинальным решением будет
воспользоваться shell-подпрограммой, и уже внутри функции
mysql_slave_running организовать цикл. Первым параметром передается
хост, а в цикле перебираются оставшиеся - номера портов. Нетрудно
заметить, что первым параметром передавать предпочтительнее наиболее
общий реквизит, не обязательно это должен быть хост:

mysql_slave_running()
{
mysql_host=$1; shift
for mysql_port in $*
do
result=`mysqladmin -h$mysql_host -P$mysql_port
$mysql_user extended-status 2>&1
| grep Slave_running | awk '{print $4}'`
case $result in
ON) ;;
OFF) /root/scripts/report.error.sh $0
"репликация на ${mysql_host}:${mysql_port}
отключена" 0 "пусто";;
*) /root/scripts/report.error.sh $0
"невозможно получить статус репликации
на ${mysql_host}:${mysql_port}" 0 "пусто";;
esac
done
}


Путаницы в скрипте становится значительно меньше, тем более, ничто не
мешает использовать для форматирования табуляцию:

mysql_slave_running "host.ru 3306 64080 64098"
mysql_slave_running "provider.ru 64098"


Доводим до совершенства

И снова, если в скрипте присутствуют повторяющиеся из строки в строку
сочетания, значит, нужен цикл. Shell имеет одну интересную и весьма
мощную, но малоизвестную возможность, многие из руководств как-то
вскользь раскрывают ее, а то и вовсе обходят стороной. Похоже,
некоторые из авторов не очень четко представляют, о чем пишут.
Возможность эта - обыкновенные двойные кавычки <<">>, вернее то, где и
каким образом трактуются shell текст и переменные, заключенные в них.
Автору пришлось изучать этот аспект shell-программирования методом
проб и ошибок.

Итак, воспользуемся кавычками для передачи в цикл параметров - группы
символов и пробелов, заключенных в кавычки, будут считаться циклом как
отдельные параметры, а функцией mysql_slave_running - как набор
параметров. Форматированием можно добиться весьма наглядного
представления:

for mysql_host in
"host.ru 3306 64080 64098"
"provider.ru 64098"
"another.host.ru 3306 64088 64068"
do
mysql_slave_running $mysql_host
done


Собираем все вместе

Целиком, уже доведенный до совершенства, скрипт будет выглядеть так:

#!/bin/sh

mysql_user="-urepcontrol -pguessable"

mysql_slave_running()
{
mysql_host=$1; shift
for mysql_port in $*
do
result=`mysqladmin -h$mysql_host -P$mysql_port
$mysql_user extended-status 2>&1
| grep Slave_running | awk '{print $4}'`
case $result in
ON) ;;
OFF) /root/scripts/report.error.sh $0
"репликация на ${mysql_host}:${mysql_port}
отключена" 0 "пусто";;
*) /root/scripts/report.error.sh $0
"невозможно получить статус репликации
на ${mysql_host}:${mysql_port}" 0 "пусто";;
esac
done
}

for mysql_host in
"host.ru 3306 64080 64098"
"provider.ru 64098"
"another.host.ru 64088 64068"

do
mysql_slave_running $mysql_host
done


Единственное, что автору так и не удалось <<победить>> в приведенном
варианте, так это расположение массива хостов и портов в середине
скрипта.


Запуск скрипта из cron

Осталось только сконфигурировать cron. В принципе, процесс ничем не
отличается от описанного в статье <<Скрипт мониторинга web-сервера
на shell>>. Объем трафика невелик, поэтому требования к частоте
запуска более мягкие, по сравнению с аналогичными требованиями
мониторинга web-сервера.

Задания, выполняемые от имени root, перечисляются в
/var/cron/tabs/root. Если его нет, можно создать файл в текстовом
редакторе или доверить создание непосредственно самому crontab:

server# crontab -e -u root


Строка, конфигурирующая cron для запуска
/root/scripts/monitor.mysql.sh каждые 33 минуты:

*/33 * * * * /root/scripts/monitor.mysql.sh


Период в 33 минуты выбран с целью развязать мониторинг серверов MySQL
с другими скриптами по времени. Развязка по времени в свою очередь
уменьшает пиковые нагрузки на канал доступа. Советую проследить режим
файла заданий - 600 (rw-) с владельцем root:wheel и наличие в нем
переменных окружения:

SHELL=/bin/sh
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin
HOME=/var/log


После внесения изменений нужно, чтобы cron перечитал список заданий:

server# crontab -u root /var/cron/tabs/root


В /var/log/cron появится запись:

Apr 28 11:11:11 server crontab[75680] REPLACE (root)


Подведение итогов

С момента снесения в cron скрипта мониторинга
/root/scripts/report.error.sh в своих протоколах будет писать:

Wed Apr 28 11:11:11 MSD 2004
/root/scripts/monitor.mysql.sh
репликация на host.ru:3306 отключена 0
пусто
Уведомление отправлено admin@host.ru, копия admin_cell_phone@nwgsm.ru


А на e-mail, указанные в скрипте будут приходить письма:

Date: Wed, Apr 28 2004 11:11:11 +0300 (MSK)
From: Charlie Root <root>
To: admin@host.ru
Subject: Сообщение об ошибке


Время: Wed Apr 28 11:11:11 MSD 2004
Скрипт: /root/scripts/monitor.mysql.sh
Действие: репликация на host.ru:3306 отключена.
Дополнительная информация:
Код ошибки: 0
Поток вывода ошибочной команды:
пусто

Например, такое письмо будет свидетельствовать о том, что MySQL сервер
<<лег>>:

Date: Wed, Apr 28 2004 11:11:11 +0300 (MSK)
From: Charlie Root <root>
To: admin@host.ru
Subject: Сообщение об ошибке


Время: Wed Apr 28 11:11:11 MSD 2004
Скрипт: /root/scripts/monitor.mysql.sh
Действие: невозможно получить статус репликации на host.ru:3306.
Дополнительная информация:
Код ошибки: 0
Поток вывода ошибочной команды:
пусто

Код ошибки и поток вывода подавляются заглушками <<0>> и <<пусто>>,
так как содержимое их не несет какой-либо достаточной смысловой
нагрузки. Таковая появляется лишь при очень неустойчивом модемном
соединении. В разделе [57]<<Разработка скрипта. Проблема первая>>
приведено объяснение этому, к тому же, поток вывода пропускается через
каналы. Хранить в транзитных переменных, затем отправлять по почте и
протоколировать исходное содержимое потока, по моему личному опыту, не
информативно.


Заключение

По предыдущим публикациям, уже вошло в привычку в заключении
акцентировать внимание на том, что данная статья не является учебным
руководством по программированию на shell, а призвана дать информацию
для размышления. Но, например, ситуация с кавычками в разделе
<<Доводим до совершенства>> несколько напоминает руководство, и,
смею надеяться, приведенный пример и объяснение, в отличие от
<<истинных>> руководств, более доходчив и понятен.
Если говорить о перспективах рассмотренного скрипта, то путей лично
мне видится два: мониторинг и/или ведение статистики каких-либо других
параметров MySQL, или же приспособление скрипта под другой сервер баз
данных.

Буду признателен за конструктивную критику.


Все права защищены. Статья не может быть скопирована или воспроизведена
с помощью любых методов или носителей информации без письменного разрешения
владельца прав на копирование.
(На opennet.ru документ размещен с разрешения автора.)
681 Прочтений •  [Разработка скрипта для протоколирования событий и мониторинга MySQL и Apache (monitor shell log apache web mysql)] [08.05.2012] [Комментариев: 0]
Добавил: Ukraine Vova
Ссылки
HTML: 
[BB Url]: 
Похожие статьи
Название Добавил Добавлено
• Разработка скрипта для протоколиров... Ukraine Vova 08.05.2012
Ни одного комментария? Будешь первым :).
Пожалуйста, авторизуйтесь для добавления комментария.

Проект входит в сеть сайтов «8Gamers Network»

Все права сохранены. 8Gamers.NET © 2011 - 2025

Статьи
Рецензия на Pressure
Рецензия на Pressure
Чтобы обратить на себя внимание, начинающие маленькие разработчики, как правило, уходят в жанры, ...
Рецензия на Lost Chronicles of Zerzura
Рецензия на Lost Chron...
Игры, сделанные без любви и старания, похожи на воздушный шар – оболочка есть, а внутри пусто. Lo...
Рецензия на The Bridge
Рецензия на The Bridge
«Верх» и «низ» в The Bridge — понятия относительные. Прогуливаясь под аркой, можно запросто перей...
Рецензия на SimCity
Рецензия на SimCity
Когда месяц назад состоялся релиз SimCity, по Сети прокатилось цунами народного гнева – глупые ош...
Рецензия на Strategy & Tactics: World War 2
Рецензия на Strategy &...
Название Strategy & Tactics: World War II вряд ли кому-то знакомо. Зато одного взгляда на ее скри...
Рецензия на игру Scribblenauts Unlimited
Рецензия на игру Scrib...
По сложившейся традиции в информационной карточке игры мы приводим в пример несколько похожих игр...
Рецензия на игру Walking Dead: Survival Instinct, The
Рецензия на игру Walki...
Зомби и продукция-по-лицензии — которые и сами по себе не лучшие представители игровой биосферы —...
Обратная связь | RSS | Донейт | Статистика | Команда | Техническая поддержка