Существует масса средств мониторинга операционной системы, но особый смысл имеет задача отловить момент возникновения проблемы и поймать причину высокой нагрузки или источник проблем c производительностью. Я называю это охотой на «грызунов» ресурсов.

Для этого я сочинил для себя несложный скрипт ratcatcher.sh который вы сможете модифицировать под свои системы и задачи.

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

Пример скрипта для сервера OpenVZ


#!/bin/bash

# чтобы не было проблем с выводом данных на кириллице 
export LC_ALL=C

# ваш лимит load average может быть другим в зависимости от количества ядер и типа задач
# например,  для сервера  OpenVZ могу рекомендовать 75-200, для гипервизора KVM - 15-45   
LALIMIT="80"

# кому отправить  отчет
EMAIL="alerts@домен.tld"

# тема сообщения
SUBJECT="WARNING-High load notification"

# Получить среднее значение нагрузки за  5 минут
F5M="$(cut -d. -f1 /proc/loadavg)"

# Сравнить с пороговым значением
RESULT="$(echo "$F5M > $LALIMIT" | bc)"


# Если не зарегистрировано превышение лимита, прекратить выполнение и выйти из выполнения
# Если зарегистрировано превышение, то  создать и отправить  отчет, но не делать это повторно до 
# понижения нагрузки ниже лимита.  Для этого при превышении  создать файл  /tmp/ratkill.flag, 
# при понижении удалить /tmp/ratkill.flag  для продолжения контроля.
#
if (( "$RESULT" == "1" )); then
  if [ -f /tmp/ratkill.flag ]; then
    exit 0
  fi
  touch /tmp/ratkill.flag
else
  if [ -f /tmp/ratkill.flag ]; then
    rm -f /tmp/ratkill.flag
  fi
  exit 0
fi

# Создать временный файл для отчета
TEMPFILE="$(mktemp)"

# Создать заголовок отчета
echo "Load average Crossed allowed limit $LALIMIT." >> $TEMPFILE
echo "Hostname: $(hostname)" >> $TEMPFILE
echo "Local Date & Time : $(date)" >> $TEMPFILE

# Использование памяти
echo "Memory-----------------------------------" >> $TEMPFILE
free -m >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
vmstat -s -Sm >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Контроль количества переключений контекста
echo "context switches:" >> $TEMPFILE
sar -w 1 5 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# наиболее активные "гости"
echo "Top loaded containers:" >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
/usr/sbin/vzlist -o veid,ip,hostname,numproc,numfile,numflock,numtcpsock,physpages,laverage -s laverage | tail -20 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

#Контроль количества сетевых соединений у гостей
echo "Top containers by net. connections count:" >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
/usr/sbin/vzlist -o veid,ip,hostname,numproc,numtcpsock -s numtcpsock | tail -20 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Общее количество сетевых подключений
echo "conntrack count" >> $TEMPFILE
wc -l /proc/net/nf_conntrack >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Утилизация дисков
echo "I/O statistic:" >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
iostat -x 2 5 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Снимок вывода top
echo "System snapshot from top:" >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
top -b | head -30 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Процессы с максимальным I/O и нагрузкой на CPU
echo "Report from dstat:" >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE
dstat --net --disk --disk-util --sys --load --proc --top-io-adv --top-cpu-adv --nocolor 5 5 >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Отчет по RAID массивам 
echo "RAID Logical device information" >> $TEMPFILE
#/opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -LALL -aAll >> $TEMPFILE
/usr/local/sbin/arcconf GETCONFIG  1 ld >> $TEMPFILE
echo "-------------------------------------------" >> $TEMPFILE

# Отправить  отчет по почте
cat $TEMPFILE > /tmp/load.txt
echo "${SUBJECT}-${F5M}" | mail -a /tmp/load.txt -s "$(hostname -s)-${SUBJECT}-${F5M}" "$EMAIL" 
rm -f $TEMPFILE

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

Для работы скрипта вам потребуется дополнительно установить утилиты sysstat и dstat. Используйте последнюю версию dstat для вашего дистрибутива иначе вы не получите нужный вывод.

Должно получаться нечто похожее на это:

image

Смотрите также:

Комментарии (11)


  1. romy4
    07.01.2016 14:59
    +3

    LA надо ловить сразу, а не раз в минуту. Можно всё пропустить.


  1. sledopit
    07.01.2016 18:22
    +6

    Но зачем? Есть же, например, atop, который умеет гораздо больше и настраивается куда гибче.
    Да и в целом систем мониторинга 100500. Чем ваш скрипт лучше (за исключением устранения NIH)?

    зы. Для скриптов есть github. Лучше делиться с сообществом скриптами через него. Глядишь, кто-нибудь и pull-request зашлёт с фиксом.


  1. Vindicar
    07.01.2016 18:45

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

    Ну это не говоря уже о других системах мониторинга.


  1. RicoX
    07.01.2016 19:31
    +9

    Чего только люди не делают лишь бы мониторинг не настраивать. Особенно «удобно» через вот такие костыли смотреть динамику и строить графики, а отловить тенденцию вообще раз плюнуть, чего там сгребти все письма за пол года и выстроить на временном графике. ИМХО — бесполезный костыль написанный от незнания принятых в отрасли средств.


  1. Acid_Jack
    07.01.2016 20:31
    +3

    Да уж, двумя awk'ами выгребать одно значение. Моветон.

    Моя конструкция выполняется в 3(!) раза быстрее:
    F5M=`cut -f1 -d' ' /proc/loadavg` && F5M=${F5M%.*}

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

    Конкретно по сабжу мало что могу сказать. У меня были случаи высокого LA в реалтайме. Ну выжрал мускул всю память и начал свопиться на диск. И шо? Попробуй понять, что его так нагрузило. Это и есть проблема.
    Вопрос оптимизации бесконечен…


    1. sledopit
      08.01.2016 00:03

      Если уж играть в shell golf, то можно и вовсе cut -d. -f1 /proc/loadavg ;)


      1. Acid_Jack
        08.01.2016 00:10

        Согласен.


    1. ashvayakov
      08.01.2016 12:10

      Да ладно вам придираться… :)
      Хотя сейчас мне самому весело смотреть на это.
      Уже не помню, скорее всего двухэтажный awk остался в скрипте от какой то предыдущей небрежной конструкции контроля порога срабатывания. Это неважно.

      sledopit, спасибо за cut -d. -f1 /proc/loadavg

      И прошу прощения, что не объяснил ясно как я понимаю назначение этого скрипта.
      Мне важно было провести диагностику в момент выявления аномального состояния, в данном случае это load average выше заданного порога.
      В вашем случае контрольный параметр может быть другим и могут быть другие диагностические процедуры.
      Это индивидуально, потому пока не увидел особого смысла скрипт выкладывать на github, но вероятно выложу.

      Данный скрипт не является универсальным инструментом, он не интерпретирует результаты тестов, но вы можете это добавить. Например если нагрузку создал mysql, то запустить скрипты диагностики для него.
      Если, например, проблема с процессом внутри гостя, то напустить vzpid на PID и т.д.
      Вариантам нет числа. Я не стал перегружать скрипт. Каждый пусть свое добавит сам если необходимо.

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

      Я хотел получить срез состояния системы, процессов и приложений в момент проблем, увидеть проблему с привязкой к процессу виновнику (крысе) и установить его принадлежность. Правильнее будет назвать скрипт не ratskill.sh, а ratcatcher.sh

      Вполне хорошая идея интегрировать подобный скрипт с zabbix или monit, можно добавить диагностику dtrace и многое другое.
      Это от вашей фантазии зависит.


      1. sledopit
        08.01.2016 17:31
        +1

        но мне сразу важно знать что было ночью.
        Вы таки почитайте про atop. Он кучу информации в более детальном виде складывает в /var/log/atop. По умолчанию собирает он информацию раз в 10 секунд.
        Правильнее будет назвать скрипт не ratskill.sh, а ratcatcher.sh
        Первый вариант забавнее. Rat Skill :)


  1. int_0x80
    08.01.2016 01:34
    +3

    … а я было грешным делом подумал, что будут ловить «крыс» (RAT — Remote Administration Tools)


  1. bosha
    12.01.2016 13:55
    +1

    Что люди не делают, лишь бы zabbix не ставить…