вторник, 13 апреля 2010 г.

Watchdog для контроля состояния линка

Для контроля состояния линка будем пинговать шлюз провайдера. Утилита ping, идущая вместе с FreeBSD и Linux, нам не подходит, т.к. не выдает никаких сообщений при отсутствии ответа проверяемого хоста. То есть нам требуется поведение присущее ping из windows, выводящей в аналогичном случае «timeout». После недолгих поисков утилита oping оказалась идеальным кандидатом.
Собственно шаблон скрипта с подробными комментариями:

#!/bin/sh
# $1 - проверяемый IP-адрес
# $2 - режим работы скрипта

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Выходим если не задан проверяемый IP
if [ -z $1 ]; then exit 1; fi

# Проверка режима работы
if [ -z $2 ]
then
# Отслеживание падения линка

# Создаем временный файл для хранения статуса линка
SAVE=$(mktemp)
# Ловим сигнал завершения и удаляем файл статуса
trap 'rm -f $SAVE; exit 0;' INT TERM QUIT
# Пингуем заданный IP-адрес с интервалом в 5 секунд
# и с помощью xargs вызываем самого себя, передавая
# результат пинга и имя файла состояния как параметры
# командной строки.
oping -4 -i 5 $1 | \
sed \
-e '1d' -e '/^--- /d' \
-e '/packets transmitted/d' \
-e '/^$/d' -u | \
xargs -n 1 --delimiter='\n' -I'{}' $0 none check "{}" $SAVE \
>> /var/log/vpn-watchdog.log
# Удаляем файл статуса
rm -f $SAVE
elif [ $2 = check -a ! -z $4 ]
then
# Watchdog
# $3 - результат пинга
# $4 - имя файла состояния

# Получение состояния линка
STATUS=$(echo $3 | grep -oE '(ms|timeout)$')
# Сравнение
if [ ! -z "$STATUS" ]
then
# Определение состояния линка и исключение
# ложного срабатывания
if [ "$STATUS" = timeout -a "$(cat $4)" != $STATUS ]
then
# Реакция на событие
echo -n "$(date +'%Y-%m-%d %H-%M-%S') TIMEOUT - Restarting... "
# Далее идет несколько строк команд
# ...
echo " done!"
fi
# Сохраняем текущее состояние для последующей проверки
echo -n $STATUS > $4
fi
fi
Достоинства данного подхода: не требуется вызывать из крона по расписанию, мониторинг идет непрерывно и, если требуется, время реакции на событие может составить одну-две секунды.

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

vik korneev комментирует...

Чем не устраивает проверка кода возврата нативной команды ping? Если пинг успешен, переменная $? содержит 0, если нет — 1.

Князь комментирует...

тем, что не хочу постоянно вызывать ping из цикла.