Tag Archives: Nagios

Nagios и ошибка проверки PINGа

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

CRITICAL — popen timeout received, but no child process

При этом ошибка не связана с реальной доступностью сервиса, все работало как положено.

Так вот, решение как оказалось простое — для проверки на пинг нужно отключить протокол IPv6.

Для этого открываем на редактирование файл /path/to/nagios/objects/commands.cfg

И там ищем два блока:

define command{
        command_name    check-host-alive
        command_line    $USER1$/check_ping -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 5
        }

и

define command{
        command_name    check_ping
        command_line    $USER1$/check_ping -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
        }

И редактируем их до такого вида:

define command{
        command_name    check-host-alive
        command_line    $USER1$/check_ping -4 -H $HOSTADDRESS$ -w 3000.0,80% -c 5000.0,100% -p 5
        }

и

define command{
        command_name    check_ping
        command_line    $USER1$/check_ping -4 -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$ -p 5
        }

То есть, всего лишь добавляем опцию -4, которая указывает, что нужно использовать только протокол IPv4.

После этого перезапуск нагиоса и проблема решена.

service nagios reload

Мониторинг графиков cacti и оповещение

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

Указывается имя rrd файла и задаются границы, если значения из rrd файла выходят за его пределы то отправляется уведомление.

balance_071813_122633_PM

 

Выше показан пример, когда задана только нижняя критическая граница.

balance_071813_123457_PM

 

А это пример когда заданы две нижние границы. При достижении значения ниже 10к создается ошибка уровня WARNING, когда значение доходит ниже порога в 5к, ошибка получает уровень CRITICAL.

Код команды в конфиге нагиоса:

define command{
    command_name    level_check
    command_line    /usr/bin/env bash /usr/local/etc/nagios/scripts/rrd_level_checker.sh $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$
}

Параметры такие же как и для скрипта по проверке соотношения.

Конфиг для сервиса в конфиге нагиоса:

define service{                
    use main-service   
    host_name levelCheck
    service_description your text
    check_command level_check!file_114.rrd!0.5!2.3
}

В этом случае заданы только по одной верхней и нижней границе (CRITICAL).

Вот пример когда заданы по две границы:

define service{                
    use main-service   
    host_name levelCheck
    service_description your text
    check_command level_check!file_114.rrd!0.5!0.8!2.3!2
}

Для примера который отображен на второй картинке параметры выглядят так:

check_command fall_check!file_114.rrd!5!10!0!0

Оповещение о падении графиков Cacti через плагин для Nagios

Написал простой плагин для nagios который работает по простому принципу: берутся значения с rrd файла за последний час и значения за этот же промежуток день назад.

После чего вычисляються соотношения текущих ко вчерашним точкам и если какое то значение выходит за заданные пределы (минимальный и максивальный уровень) — плагин сигнализирует об ошибке.

(на рисунку прозрачным цветом нарисован график за предыдущий день)

Для nagios нужно прописать в objects/commands.cfg следующие строки

define command{
    command_name    fall_check
    command_line    /usr/bin/env bash /usr/local/etc/nagios/scripts/rrd_fall_checker.sh $ARG1$ $ARG2$ $ARG3$ $ARG4$ $ARG5$
}

ARG1 — имя rrd файла (без абсолютного пути, он настраивается в самом файле плагина)

А дальше возможны варианты:

Если указаны только аргументы 2 и 3:

  • ARG2 — минимальный критический порог
  • ARG3 — максивальный критический порог (0 или пусто -верхней границы не задано)

Если указаны все аргументы то задаются отдельно значения для уровня критического уровня и предупреждения (нагиос будет показывать статус CRITICAL, WARNING соответственно):

  • ARG2 — минимальный критический порог
  • ARG3 — минимальный порог предупреждения
  • ARG4 — максивальный критический порог (0 или пусто -верхней границы не задано)
  • ARG5 — максимальный порог предупреждения

Конфиг для сервиса на проверку выглядит примерно так:

define service{                
    use main-service   
    host_name fallCheck
    service_description your text
    check_command fall_check!file_114.rrd!0.5!2.3
}

В данном случае задан порог с 0.5 до 2.3 и при выходе за заданные границы будет критическое уведомление.

Либо так:

define service{                
    use main-service   
    host_name fallCheck
    service_description your text
    check_command fall_check!file_114.rrd!0.5!0.8!2.3!2
}

В этом случае, если ратио опустится ниже 0.8 — будет ошибка уровня WARNING. Если ниже 0.5 то уже CRITICAL. Аналогично и для верхней границы.

Если нужно указать только нижние границы то можно использовать такую запись:

check_command fall_check!file_114.rrd!0.5!0.8!0!0

Сам плагин доступен на гитхабе: https://github.com/unkn0wn404/Nagios.FallChecker

Требует наличия bash и php. Можно было бы обойтись и без пхп конечно, но было лень маяться с логикой проверки ратио в баше.

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

Переносим Cacti и Nagios на другой сервер

Приветствую всех читателей моего уютного бложика!

Решил я на днях отделить систему мониторинга от обычных рядовых серверов и взял под эти нужды простенький впс на базе VDSManager. И стал я все настраивать да переносить, никаких сложностей не возникало, да вот только после того как все подготовительные работы были выполнены, оказалось что графики почему то не рисуются. При чем rrd файлы были на месте, но через веб интерфейс ответ rrdtool был пустым. Я пробовал выполнить от себя команду которая в дебаг режиме пишется в самом какти и в ответ получал либо

No match

либо

Bad system call

Все попытки справиться с этим у меня не увенчались успехом и в итоге я решил что я нифига не понимаю в фрибсд и передал работу разобраться с этой проблемой сторонним админам за деньги.

Несколько дней ожидания и админы дали свой вердикт — судя по всему vdsmanager накладывает какие то свои ограничения на ОС, что не позволяет правильно работать rrdtool которая должна рисовать графики.

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

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

Так вот, исходя из этого опыта несколько советов как правильно переехать на новое место обитания мониторинга.

После того как на новом сервере настроены всякие веб сервера, пхп, мускули и т.п., то есть проделана вся работа как и для установки нового кактуса, делаем следующее:

  1. На старом сервере пакуем всю папку /usr/local/www/cacti и делаем дамп базы cacti
  2. Делаем дампы rrd файлов (как это сделать немного ниже)
  3. Скидываем надампеное на новый сервер
  4. На новом сервере копируем с заменой файлы config.php и все файлы из scripts/ без замены файлов, то есть добавляем то,  чего не хватает на новом.
  5. Восстанавливаем из дампов rrd файлы
  6. Ставим скрипт кактуса в крон как и при сетапе нового сервера.

Как сделать бекап и восстановление.

Вообще говоря есть стандартная функциональность rrdtool делать dump & restore. Почему мне этого было мало? — файлов несколько десятков, а запускать команду нужно на каждый файл отдельно, это просто издевательство так делать.

Выход прост — нагуглил уже готовый скрипт для масового переноса —  вот на этом форуме (второй пост)

Для надежности продублирую скрипт еще тут

 

#!/bin/bash

set_dump_values () {
        src_ftype="rrd"
        dest_ftype="xml"
}

set_restore_values () {
        src_ftype="xml"
        dest_ftype="rrd"
}

set_search_path () {
        search_path=$1
        log_path="${search_path}/rra_batch.log"
}

print_usage () {
        echo "Usage: $0 [COMMAND] [-c | -d [PATH]]"
        echo " "
        echo "Summary:"
        echo "Does either an rrdtool dump or an rrdtool restore of all files in the search directory."
        echo "This script will not look for .rrd files or .xml files to use outside of the specified search directory, but will recursively search throught the specified directory."
        echo " "
        echo "Commands:"
        echo "dump     Dumps files with .rrd in the file name to an XML file."
        echo "dump-nh  Dumps files with .rrd in the file name to an XML file."
        echo "         This command puts no headers in the output XML for compatibility with rrdtools 1.2.x."
        echo "restore  Restores files with .xml in the file name to an RRD file."
        echo " "
        echo "Options:"
        echo "-c  Search current working directory."
        echo "-d  Specify search directory."
        exit 0
}

log () {
        echo "[`date +%Y%m%d%H%M%S`] $1" >> ${log_path}
}

rrdtool_command () {
        case $1 in
                dump)
                        log "Dumping \"$name\" to ${new_name}.${dest_ftype}"
                        rrdtool $1 "$name" > "${new_name}.${dest_ftype}"
                        ;;
                dump-nh)
                        log "Dumping with no header \"$name\" to ${new_name}.${dest_ftype}"
                        rrdtool dump "$name" --no-header > "${new_name}.${dest_ftype}"
                        ;;
                restore)
                        log "Restoring \"$name\" to ${new_name}.${dest_ftype}"
                        rrdtool $1 "$name" "${new_name}.${dest_ftype}"
                        ;;
                *)
                        log "Illegal command: ${1}"
                        exit 1
                        ;;
        esac
}

case $1 in
        dump)
                set_dump_values
                ;;
        dump-nh)
                set_dump_values
                ;;
        restore)
                set_restore_values
                ;;
        *)
                print_usage $0
                ;;
esac

case $2 in
        -d)
                set_search_path $3
                ;;
        -c)
                set_search_path `pwd`
                ;;
        *)
                print_usage $0
                ;;
esac

echo "Logging output to $log_path..."
log "Search path set to \"$search_path\"."

for name in $(find $search_path -type f -print | grep [.]${src_ftype})
do
        if [ $name != "." ] ; then
                new_name=""
                OIFS=$IFS
                IFS='.'
                for name_element in $name
                do
                        if [ $name_element != $src_ftype ] ; then
                                if [ -z $new_name ] ; then
                                        new_name=$name_element
                                else
                                        new_name="${new_name}.${name_element}"
                                fi
                        fi
                done
                IFS=$OIFS
                if [ -n $name ] ; then
                        rrdtool_command $1
                fi
        fi
done

log "Finished batch."
echo "Done."
exit 0

Пользоваться им очень просто. Сохраняем скрипт где угодно, пусть это будет ~/rrdmove.sh

После этого на старом сервере:

bash ~/rrdmove.sh dump -d /usr/local/www/cacti/rra/
# создаем архив с дампами
tar -czf ~/rrd.tar.gz /usr/local/www/cacti/rra/*.xml
# кидаем файл на новый сервер
scp ~/rrd.tar.gz user@server:~/

После чего на новом сервер надо закинуть этот же скрипт куда либо, я для примера возьму тот же самый файл ~/rrdmove.sh и делаем следующее:

cd /usr/local/www/cacti/rra/
# распаковываем дампы
tar -xzf ~/rrd.tar.gz
# запускаем скрипт восстановления
bash ~/rrdmove.sh restore -d /usr/local/www/cacti/rra/
# удаляем дампы, они больше не нужны
rm /usr/local/www/cacti/rra/*.xml

Кто то может спросить — почему бы просто не скопировать rrd файлы и не дрочить мозг? — И я отвечу, что именно такой способ у меня возник первым. Но, как оказалось, rrd файлы платформо-зависимы, что означает что не всякие rrd файлы подойдут для новой системы. Отсюда и необходимость в их дампе/ресторе.

Касательно Nagios — там все просто — нужно скопировать и перенести папку /usr/local/etc/nagios/

Только не трогать /usr/local/www/nagios, во всяком случае cgi скрипты там, потому что они тоже платформо-зависимы и я потратил пару часов на то, что бы определить, почему бляха cgi скрипты не работают. Там только конфиг файл стоит перенести со старого, да и то, лучше его поправить заново ручками, а то может на новом сервере нагиос другой версии и там файл немного отличается.

Позже еще будет пост о настройке nagios, а то сразу я его поставил и он стоял без дела фактически  =)

Уютненький сервер на FreeBSD: мониторинг, мать его.

И недалеко отходя от темы FreeBSD, позаботимся сразу вопросом стабильности работы, поставим сервисы мониторинга: nagios + cacti.

Начнем с первого: Nagios

Учитывая что он использует FCGI, в первом попавшемся мануале предлагается установка apache, но мы то не такие, без крайней необходимости не будем его ставить. Поэтому будет использовать fcgiwrap под nginx!

cd /usr/ports/www/fcgiwrap
make install clean
echo 'fcgiwrap_enable="YES"' >> /etc/rc.conf
echo 'fcgiwrap_user="www"' >> /etc/rc.conf
echo 'fcgiwrap_socket="unix:/tmp/fcgiwrap.sock"' >> /etc/rc.conf
# последнее очень важно, так как используя путь по умолчанию nginx получает ошибку доступа к сокету, а по этому адресу все ок =)

В nginx.conf добавляем

upstream fcgi-backend
{
  server unix:///tmp/fcgiwrap.sock;
}

# Далее ставим сам nagios:
cd /usr/ports/net-mgmt/nagios
make install clean
echo 'nagios_enable="YES"' >> /etc/rc.conf
service nagios start

Далее нам понадобится создать файл с юзерами для nagios, который будет использоваться при проверке запроса на авторизацию из браузера.

Обычно его можно создать утилитой htpasswd которая входит в состав апача, но так как мы его не ставили, у нас ее нету. Можно восспользоваться, к примеру, вот этим http://seriyps.ru/crypt/htpasswd/ сервисом.

И вставляем запись в формате user:crypterPassword в /path/to/passwd файлик, путь к которому нужно будет прописать в конфиге nginx позже.

Пример конфиг файла от http://rlaskey.org/words/897/nagios-nginx-freebsd/

server {
listen 80 default;
server_name _;

index index.html index.php;
root /usr/local/www;

# IP and IP ranges which should get access
allow 10.0.0.0/24;
allow 10.1.0.1;
# all else will be denied
deny all;

# basic HTTP auth
auth_basic "Restricted";
auth_basic_user_file htpasswd;

location ~ \.cgi$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/fcgiwrap/fcgiwrap.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param REMOTE_USER $remote_user;
}

location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

Изменять его под себя прийдется уже вам самостоятельно.

Так же нужно отредактировать конфиг nagios, который находится в /usr/local/etc/nagios/. Там нужно создать (а точнее переименовать примеры конфиг файлов *.cfg-sample (а также objects/*.cfg-sample).

Если вы для авторизации будете использовать логин отличный от nagiosadmin, то его нужно прописать в  cgi.cfg:

authorized_for_all_services=username
authorized_for_all_hosts=username

authorized_for_all_service_commands=username
authorized_for_all_host_commands=username

authorized_for_system_information=username

authorized_for_configuration_information=username

authorized_for_system_commands=unkn0wn

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

Так же я, иногда забываю писать что нужно перезапустить какой то сервис, это нужно помнить самостоятельно, после изменений конфига сервиса этот сервис нужно перезапустить.

С nagios на этом моменте закончено.

Часть 2: Cacti

При сетапе частично руководствовался инструкцией http://habrahabr.ru/blogs/bsdelniki/71087/

Данные он будет собирать через smtp, подготовим ему базу:

cd /usr/ports/net-mgmt/net-snmp/
make install clean
echo 'snmpd_enable="YES"' >> /etc/rc.conf
echo 'snmpd_conffile="/usr/local/etc/snmpd.conf"' >> /etc/rc.conf
ee /usr/local/etc/snmpd.conf

Вставляем туда строку

rocommunity changeme

Выходим, сохраняем.

service snmpd start
snmpget -c changeme -v1 localhost .1.3.6.1.2.1.1.1.0
# проверяем работоспособность, должны получить что то типа
# SNMPv2-MIB::sysDescr.0 = STRING: FreeBSD ax3.local.net 8.2-STABLE FreeBSD 8.2-STABLE #0

Идем по душу кактуса

cd /usr/ports/net-mgmt/cacti
make install clean

С кактусом дальше процесс был в общем то идентичный тому, как описано в статье по ссылке выше.

Вкратце перепишу на случай недоступности последней:

Создаем пользователя и базу для cacti, импортируем в нее дамп из /usr/local/share/cacti/cacti.sql

Добавляем в крон

*/5 * * * * /usr/local/bin/php /usr/local/share/cacti/poller.php > /dev/null 2>&1

Копируем или делаем симлинк /usr/local/share/cacti/ в место, которое будет настроено на обработку web серверов, я сделал симлинк в /usr/local/www/cacti и далее конфиг nginx аналогичный как для nagios, только убрать авторизацию базовую, кактус использует свою через базу данных.

На этом пока все, оставляем кактус рисовать графики.