Я работаю админом и в моей зоне ответственности находится ряд серверов: роутеры, серверы БД, терминальные серверы и т.д. И хочется быть в курсе, если какойто из серверов вдруг пропал из сети — где-то упал линк с удаленной сетью, где-то вдруг произошел хрестоматийный случай с техничкой, шваброй и кабелем, где-то еще какой форс-мажор случился. И при этом не хочется заморачиваться с тяжеловесными системами мониторинга, вроде Zabbix.
Хочу поделиться с обществом своим скриптом для своевременного уведомления о пропавшей связи с серверами. Скрипт написан на Perl и крутится на моем рабочем десктопе в среде Debian GNU/Linux. Скорей всего без лишних приседаний запустится и в другом дистрибутиве линукса.
Итак, скрипт с комментариями:
Теперь оговорки по скрипту.
У перла, а конкретно у Net:Ping есть особенность. Если использовать встроенный перловый модуль Net::Ping с типом пинга ICMP, то потребуются привилегии суперпользователя root. Это связано с реализацией ICMP-пинга в этом модуле через RAW-сокеты, которыми имеет право пользоваться только root. Поэтому я использовал в этом скрипте Net::Ping::External, который реализует пинг через внешние вызовы.
Помимо уведомления админа всплывающими нотифами можно дописать, например, запись информации о падениях-поднятиях в текстовый лог (свой или через syslog), можно отправлять сообщения на мыло, в джаббер, смс на телефон и т.д. Полный полет для фантазии.
До кучи, можно дописать проверку на живость сервисов, например веб, почты, фтп, самбы. Но это уже выйдет за рамки простого пинговальщика и будет похоже на тяжеловесные системы мониторинга.
Хочу поделиться с обществом своим скриптом для своевременного уведомления о пропавшей связи с серверами. Скрипт написан на Perl и крутится на моем рабочем десктопе в среде Debian GNU/Linux. Скорей всего без лишних приседаний запустится и в другом дистрибутиве линукса.
Итак, скрипт с комментариями:
#!/usr/bin/perl
# Подключаем модули:
use strict; # Включаем строгое определение переменных.
use Net::Ping::External qw(ping); # Подключаем модуль для ICMP-пинга
# Конфигурационные переменные:
my $tries = 3; # Количество попыток пинга каждого хоста
my $timeout = 5; # Таймаут пинга
my $interval = 5; # Интервал между проверками
# Хеш-массив с хостами для проверки. Имя для отображения => айпи или хостнейм
my %hosts = (
"HOST-1" => "10.0.0.1",
"HOST-2" => "10.0.0.2"
);
# Далее, собственно, сам скрипт
# Определеяем вспомогательный хеш, в котором будут храниться состояния хостов
my %state = ();
# По умолчанию все хосты живые
while (my ($name, $ip) = each(%hosts)) {
$state{$name} = "UP";
}
# Запускаем бесконечный цикл
while () {
# Массивы для вновь упавших и вновь поднявшихся хостов
my @uphosts = ();
my @downhosts = ();
# Проходим в цикле весь хеш проверяемых хостов
while (my ($name, $ip) = each(%hosts)) {
# Счетчик ответов сбрасываем в ноль
my $cnt = 0;
# Выполняем нужное количество пингов, увеличивая счетчик ответов при удачных пингах
for (my $i = 1; $i <= $tries; $i++) {
if (ping(hostname => $ip, timeout => $timeout)) {
$cnt++;
}
}
# Если хост не ответил ни разу, он предположительно мертв
if ($cnt == 0) {
# Если до этого он был жив, надо уведомить админа о вновь упавшем хосте, добавляем в список
if ($state{$name} eq "UP") {
$state{$name} = "DOWN";
push(@downhosts, $name);
}
# Если хост ответил хоть на один пинг - он жив
} else {
# Снова проверяем предыдущее состояние
if ($state{$name} eq "DOWN") {
$state{$name} = "UP";
push(@uphosts, $name);
}
}
}
# Поверки закончены, проверяем списки и, если есть хосты с изменившимися состояниями,
# уведомляем админа средствами libnotify
if (scalar(@uphosts) > 0) {
my $lst = join(", ", @uphosts);
`notify-send -u normal NetMon "Hosts becomes up: $lst"`;
}
if (scalar(@downhosts) > 0) {
my $lst = join(", ", @downhosts);
`notify-send -u critical NetMon "Hosts becomes down: $lst"`;
}
# Отдыхаем заданный интервал времени
sleep($interval * 60);
};
Теперь оговорки по скрипту.
У перла, а конкретно у Net:Ping есть особенность. Если использовать встроенный перловый модуль Net::Ping с типом пинга ICMP, то потребуются привилегии суперпользователя root. Это связано с реализацией ICMP-пинга в этом модуле через RAW-сокеты, которыми имеет право пользоваться только root. Поэтому я использовал в этом скрипте Net::Ping::External, который реализует пинг через внешние вызовы.
Помимо уведомления админа всплывающими нотифами можно дописать, например, запись информации о падениях-поднятиях в текстовый лог (свой или через syslog), можно отправлять сообщения на мыло, в джаббер, смс на телефон и т.д. Полный полет для фантазии.
До кучи, можно дописать проверку на живость сервисов, например веб, почты, фтп, самбы. Но это уже выйдет за рамки простого пинговальщика и будет похоже на тяжеловесные системы мониторинга.