пятница, 9 июля 2010 г.

Обработчики событий (Event handlers)


Введение
Обработчики событий - это дополнительные системные команды (скрипты или исполняемые файлы), которые выполняются каждый раз при изменении состояния проверки хоста (host) или сервиса (service).
Основное предназначение обработчиков событий заключается в предоставлении возможности автоматически исправлять ошибки, прежде кто-либо из контактных лиц будет оповещен о проблеме. Ниже приведены другие варианты использования обработчиков событий:
·      Перезапуск отказавшего (проблемного) сервиса
·      Регистрация заявки на устранение неисправности в системе helpdesk
·      Журналирование информации о событии (например, сохранение в базе данных)
·      Периодическая автоматическая перезагрузка хоста*
·      и т.д.

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

Когда выполняются обработчики событий?
Обработчики событий выполняются, когда сервис или хост:
·      находится в проблемном состоянии типа SOFT
·      впервые перешел в проблемное состояние типа HARD
·      восстановился после проблемного состояния типа SOFT или HARD
Состояния проверок типа SOFT и HARD подробно описываются здесь.


Типы обработчиков событий
В Icinga/Nagios выделяются несколько типов обработчиков событий, с помощью которых можно организовать обработку изменений состояния хоста или сервиса:
·      Глобальный обработчик событий хоста (Global host event handler)
·      Глобальный обработчик событий сервиса (Global service event handler)
·      Локальные обработчики событий хоста (Host-specific event handlers)
·      Локальные обработчики событий сервиса (Service-specific event handlers)
Глобальные обработчики событий хоста и сервиса выполняются при изменении состояния любого хоста или сервиса, соответственно. Глобальные обработчики событий выполняются до обработки локальных и задаются с помощью опций  global_host_event_handler и global_service_event_handler в основном конфигурационном файле.
Локальные хосты и сервисы могут иметь свой собственный обработчик событий, который будет выполняться при изменении состояния проверки. Задать данный обработчик можно с помощью директивы event_handler в графе описания (определения) хоста или сервиса (define host и define service ). Локальные обработчики выполняются сразу же после Глобальных (если они заданы).

Включение обработчиков событий
Обработчики событий могут быть включены или выключены глобально для всей программы с помощью директивы enable_event_handlers в основном конфигурационном файле.
Локальные обработчики событий могут быть включены или выключены с помощью опции event_handler_enabled в области определения хоста или сервиса . Если выключена глобальная переменная enable_event_handlers   локальные обработчики событий так же не будут выполняться.

Порядок выполнения обработчиков событий
Как упоминалось выше, глобальные обработчики событий хоста и сервиса выполняются прежде, чем будут выполнены локальные.
Для проблемного состояния типа HARD, а также сразу после восстановления хоста или сервиса из проблемного состояния, выполняется обработчик событий, но только после того, как будет послано уведомление.

Написание команд обработчика событий
Командами обработчика событий могут быть любые файлы, которые можно выполнить в командной строке (например, это могут быть perl-скрипты или скрипты командной оболочки). Как минимум, скрипты должны принимать на входе качестве аргументов следующие макросы:
Для Сервисов: $SERVICESTATE$ , $SERVICESTATETYPE$ , $SERVICEATTEMPT$
Для Хостов: $HOSTSTATE$ , $HOSTSTATETYPE$ , $HOSTATTEMPT$
Скрипты должны обрабатывать данные аргументы и, основываясь на полученных значениях, предпринимать необходимые действия. Для лучшего понимания разберите пример приведенный ниже .

Подсказка
Дополнительные демонстрационные сценарии обработчиков событий могут быть найдены в подкаталоге contrib/eventhandlers/ дистрибутива Icinga. Некоторые из этих сценариев демонстрируют использование внешних команд , чтобы реализовать отказоустойчивость и распределенную среду мониторинга.

Полномочия команд обработчика событий
Команды обработчика событий обычно выполняться с полномочиями процесса Icinga. В некоторых случаях это может оказаться неудобным, например, если вы хотите написать обработчик событий, который выполняет  перезапуск сервиса (данная процедура требует наличия полномочий пользователя root).
В идеале, необходимо определить обработчики событий, которые вы хотите внедрить, и предоставить пользователю Icinga полномочия для выполнения необходимых системных команд. Либо, вместо этого, вы можете использовать утилиту sudo .

Пример обработчика событий сервиса
Данный пример предполагает, что Вы осуществляете мониторинг сервера HTTP на локальной машине и определили restart-httpd как команду локального обработчика событий сервиса HTTP. Также предполагается, что Вы установили значение опции max_check_attempts контролируемого сервиса 4 или более (то есть сервис будет проверяется 4 раза после возникновения проблемы, прежде чем статус проверки перейдет в состояние типа HARD). Ниже представлен пример определения сервиса с обработчиком событий:
 define service {
        host_name somehost
        service_description HTTP
        max_check_attempts 4
        event_handler restart-httpd
        ...
        }
После определения сервиса необходимо определить команду обработчика событий restart-httpd как показано ниже. Обратите особое внимание на макросы, которые передаются в командной строке (command_line), они важны!
define command {
        command_name restart-httpd
        command_line /usr/local/icinga/libexec/eventhandlers/restart-httpd $SERVICEATTEMPT$ $SERVICESTATETYPE$ $SERVICESTATE$
        }
Теперь, давайте напишем скрипт обработчика событий  /usr/local/icinga/libexec/eventhandlers/restart-httpd.
#!/bin/sh
#
# скрипт обработчика событий перезапускающий веб-сервер на локальной машине
#
# Примечание: Этот скрипт перезапустит веб-сервер в случае, если сервис
# будет в проблемном состоянии типа SOFT 3 раза подряд (таким образом, скрипт пытается перезапустить сервис до того, как будет выполнено оповещение) или, если веб-сервер, так или иначе,
# умудриться перейти в проблемное состояние типа HARD (при переходе в данное состояние сработает оповещение).
#


#, В каком состоянии находится сервис HTTP?
case "1$" in
OK)
        # сервис только что восстановился, так что ничего не делайте...
        ;;
WARNING)
        # Мы не обрабатываем состояние warning поскольку сервис, возможно все еще запущен...
        ;;
UNKNOWN)
        # Не известно, что могло бы вызывать ошибку, так что лучше ничего не делать...
        ;;
CRITICAL)
        # Ага! У сервиса HTTP, кажется, есть проблема - возможно, необходимо перезапустить его...

        # это состояние типа SOFT или HARD?
        case "2$" in
               
        # Мы находимся в проблемном состоянии типа SOFT, это означает, что Icinga находится на полпути к тому, чтобы перейти в состояние типа HARD и произвести оповещение контактов...
        SOFT)
                       
                # Сколько проверок было произведено ранее? Мы не хотим перезапускать веб-сервер при возникновении состояния типа SOFT впервые, поскольку это может быть просто ложное срабатывание или какая либо случайность!
                case "3$" in
                               
                # Ожидаем, пока количество не успешных проверок не будет равно 3 прежде, чем перезапустить веб-сервер.
                # Если 4 раза проверка выполнилась неуспешно (даже, несмотря на перезагрузку сервиса при 3-й проверке), то состояние проверки измениться на HARD и будет выполнено оповещение контактов.
                # Мы надеемся, что перезапуск веб-сервера произойдет успешно, сервис восстановится. При этом 4-ая проверка переведет сервис в нормальное состояние типа SOFT. Если это произойдет, уведомление не будет оправлено, поскольку проблема будет решена.
                3)
                        echo -n "Restarting HTTP service (3rd soft critical state)..."
                        # Вызов init сценария, чтобы перезапустить сервер HTTPD
                        /etc/rc.d/init.d/httpd restart
                        ;;
                        esac
                ;;
                               
        # сервис HTTP, каким-то образом попал в проблемное состояние типа HARD и проблема не была решена.
        # По идее, сервис должен был быть перезапущен выше по коду, но по каким-то причинам этого не произошло. Так давайте же дадим ему еще одну попытку? 
        # Примечание: Контактные лица, указанные при определении сервиса, уже были оповещены о проблеме (если Вы не отключили уведомления для этого сервиса)
        HARD)
                echo -n "Restarting HTTP service..."
                # Вызов init сценария, чтобы перезапустить сервер HTTPD
                /etc/rc.d/init.d/httpd restart
                ;;
        esac
        ;;
esac
exit 0

Данный демонстрационный скрипт, будет пытаться перезапустить веб-сервер на локальной машине в следующих случаях:
·      После того, как сервис был перепроверен в 3-ий раз и находится в состоянии CRITICAL типа SOFT
·      После того, как сервис перейдет в состояние CRITICAL типа HARD
Приведенный скрипт должен теоретически перезапустить и веб-сервер и решить проблему прежде, чем сервис перейдет в проблемное состояние типа HARD. Но, что будет, в случае, если сервис все же перейдет в проблемное состояние типа HARD и предусмотренная последняя перезагрузка не поможет? Именно на этот случай был реализован защитный механизм, который предотвращает непрерывное выполнение команды обработчика событий. Другими словами команда обработчика событий будет выполнена только в том случае, если сервис впервые оказался в проблемном состоянии типа HARD.
Это - все! Обработчики событий довольно просто написать и реализовать, так что пробуйте, экспериментируйте и радуйтесь тому, что у вас получится. :)

2 комментария: