В предыдущей записи я рассказывал как посредсвом zabbix настроить мониторинг nginx. В этой записи речь пойдет о состоянии tcp-соединений.
Вообщем-то отслеживать состояние tcp-соединений не всегда нужно, но иногда очень полезно, когда число оных переваливает за сотни.
Часть 1. Скрипт
Создадим файл ~/zabbix/scripts/tcp_status.sh с примерно таким содержанием (Версия 2.0, спасибо p2n):
#!/bin/bash
HOST=`/bin/hostname`
SERVER='zabbix.yourdomain.com'
/bin/ss -ant | awk "{if (NR>1) {state[\$1]++}} END {host = \"${HOST}\"; \
for (i in state) {s=i; \
sub (/ESTAB/, \"establ\", s); sub (/LISTEN/, \"listen\", s); sub (/SYN-SENT/, \"synsent\", s); \
sub (/SYN-RECV/, \"synrecv\", s); sub (/FIN-WAIT-1/, \"finw1\", s); sub (/FIN-WAIT-2/, \"finw2\", s); \
sub (/CLOSE-WAIT/, \"closew\", s); sub (/TIME-WAIT/, \"timew\", s); print host, \"tcp.\"s, state[i]}}" \
| ~/zabbix/bin/zabbix_sender --zabbix-server ${SERVER} -s ${HOST} --port '10051' -i - >/dev/null 2>&1
echo "1"
exit 0
Часть 2. Настройка агента
В Конфиг агента добавляем строку:
UserParameter=tcp.all,~/zabbix/scripts/tcp_status.sh
После чего перезапускаем:
/etc/init.d/zabbix-agent restart
Часть 3. Шаблон
Готовый шаблон с графиком и триггерами:
Образец графика:
5 комментариев “Zabbix для мониторинга состояния tcp-соединений”
Супер, благодарю!
И можно несколько универсальней, ипользуя значения для hostname и server из конф. файла.
Тире в данных, подаваемых на стандартный ввод, указывает, что имя узла сети должно быть взято из того же конфигурационного файла.
#!/bin/bash
/sbin/ss -ant | awk "{if (NR>1) {state[\$1]++}} END {host = \"-\"; \
for (i in state) {s=i; \
sub (/ESTAB/, \"establ\", s); sub (/LISTEN/, \"listen\", s); sub (/SYN-SENT/, \"synsent\", s); \
sub (/SYN-RECV/, \"synrecv\", s); sub (/FIN-WAIT-1/, \"finw1\", s); sub (/FIN-WAIT-2/, \"finw2\", s); \
sub (/CLOSE-WAIT/, \"closew\", s); sub (/TIME-WAIT/, \"timew\", s); print host, \"tcp.\"s, state[i]}}" \
| /usr/bin/zabbix_sender -c /etc/zabbix/zabbix_agentd.conf -i - 2>&1
echo "1"
exit 0
Как обычно, очевидное то я вовремя не заметил: названия состояний сокетов в выводе ss немного отличаются от таковых у netstat, секция BEGIN тут не нужна вовсе, а в строках-заменителях можно выбросить общую часть «за скобки» для уменьшения размера программы:
/usr/sbin/ss -ant | awk "{if (NR>1) {state[\$1]++}} END {host = \"${HOST}\"; for (i in state) {s=i; sub (/ESTAB/, \"establ\", s); sub (/LISTEN/, \"listen\", s); sub (/SYN-SENT/, \"synsent\", s); sub (/SYN-RECV/, \"synrecv\", s); sub (/FIN-WAIT-1/, \"finw1\", s); sub (/FIN-WAIT-2/, \"finw2\", s); sub (/CLOSE-WAIT/, \"closew\", s); sub (/TIME-WAIT/, \"timew\", s); print host, \"tcp.\"s, state[i]}}" | ~/zabbix/bin/zabbix_sender --zabbix-server ${SERVER} -s ${HOST} --port '10051' -i - >/dev/null 2>&1
Как-то так, полагаю, получше должно быть :)
Спасибо, обновил скрипт.
Блин, не увидел вовремя замечание про тэги. Попробую оформить в виде кода этот «ужас» :) Если получится — Раск удали мой предыдущий камент, пожалуйста.
Основную часть можно оптимизировать, возложив всю работу на AWK и избавиться от кучи форков:
/usr/sbin/ss -ant | awk "BEGIN {host = \"`/bin/hostname`\"} {if (NR>1) {state[\$1]++}} END {for (i in state) {s=i; sub (/ESTAB/, \"tcp.establ\", s); sub (/LISTEN/, \"tcp.listen\", s); sub (/SYN_SENT/, \"tcp.synsent\", s); sub (/SYN_RECV/, \"tcp.synrecv\", s); sub (/FIN_WAIT1/, \"tcp.finw1\", s); sub (/FIN_WAIT2/, \"tcp.finw2\", s); sub (/CLOSE_WAIT/, \"tcp.closew\", s); sub (/TIME_WAIT/, \"tcp.timew\", s); print host, s, state[i]}}" | ~/zabbix/bin/zabbix_sender --zabbix-server ${SERVER} -s ${HOST} --port '10051' -i - >/dev/null 2>&1
Спасибо за готовые скрипты =). Оставлю свой вклад:
netstat достаточно медленно работает. На сервере с 40 тыс. соединений он отдаёт их количество за 30 секунд. Заббикс не дожидается его. Поэтому лучше использовать утилиту ss. Плюс там в скрипте ошибка закралас — ‘let «closew += 0″‘ два раза повторяется.
Вот так выглядит средняя часть моего скрипта:
ss -na | awk ‘{print $1}’| sort |uniq -c >${TMPF}
establ=`cat $TMPF | grep «ESTAB» |awk ‘{print $1}’`
let «establ += 0»
synsent=`cat $TMPF | grep «SYN-SENT» |awk ‘{print $1}’`
let «synsent += 0»
synrecv=`cat $TMPF | grep «SYN-RECV» |awk ‘{print $1}’`
let «synrecv += 0»
finw1=`cat $TMPF | grep «FIN-WAIT-1» |awk ‘{print $1}’`
let «finw1 += 0»
finw2=`cat $TMPF | grep «FIN-WAIT-2» |awk ‘{print $1}’`
let «finw2 += 0»
timew=`cat $TMPF | grep «TIME-WAIT» |awk ‘{print $1}’`
let «timew += 0»
closew=`cat $TMPF | grep «CLOSE-WAIT» |awk ‘{print $1}’`
let «closew += 0»
listen=`cat $TMPF | grep «LISTEN» |awk ‘{print $1}’`
let «listen += 0»