Итак, поехали. Пара говорок — я описываю мониторинг со стороны nagios, поэтому как и что настраивать на серверах, которые надо мониторить — упоминаю в общем виде. И второе — я не люблю имена mibs, стараюсь использовать oid, циферки. Если по ним искать в гугле, то вы найдёте и их имена, и соседние мибы. Собственно, знать нужный oid — это 2/3 дела в случае snmp-мониторинга.
В качестве языка программирования в данном случае я предпочитаю perl — его проще отлаживать и переносить между платформами.
Я обязательно буду приводить примеры плагинов (иначе для чего бы я эту статью затеял), в том числе может быть стандартных, потому что уже не помню, что шло в комплекте, что искалось с миру по нитке и допиливалось. Помню лишь, что писал сам с нуля, там мои копирайты стоят.
Для самостоятельного осмотра дерева oid рекомендую стандартную утилиту snmpwalk. Сам нагиос у меня а) версии 3.x, б) установлен на FreeBSD, поэтому пути часто будут типичные для Free и нетипичные для linux.
Мониторинг windows-серверов
Используем банальный встроенный snmp (который есть в windows-серверах начиная с windows 2000). Сервис этот по-умолчанию не стоит, его надо добавить, настроить community name (snmp пароль) и ip адреса, с которых можно обращаться к сервису (по-умолчанию пароль public и разрешен только локальный ip). Описание windows mibs можно легко найти в инете.
Стандартный плагин check_disk_snmp.pl позволяет мониторить диски по имени (что важно, потому что порядок дисков в дереве snmp может менять после перезагрузки; если мы говорим именно о сервере, который перезагружают 1-2 раза в год; за это время у него может нарасти слой «внешних» — fibrechannel или iscsi — дисков. Буквы у них сохраняться после перезагрузки, а вот порядок в дереве snmp — не факт). А так же он позволяет мониторить состояние ОЗУ — свободно, занято, swap.
Стандартный плагин check_snmp_load.pl позволяет мониторить нагрузку cpu на сервере, а стандартные же плагины check_tcp и check_udp — доступность сетевых портов. Ибо для чего еще нужен сервер, как не для обслуживания сетевых запросов!
Описание стандартных oid, на которые отзывается windows доступно здесь. Там есть и CPU, и ОЗУ, и устройства хранения данных (в том числе по типу — CDROM, Floppy, HDD), запущенные процессы и установленные программы.
Мониторинг unix-серверов
Тут тоже всё просто. Устанавливаете на сервере пакет net-snmp, настраиваете snmpd.conf. В последних версиях там ад и хаос, я предпочитаю (вот такой я консерватор)
rocommunity vasik 10.0.9.1
Вышепомянутый check_disk_snmp.pl умеет мониторить и unix-сервера. Плюс есть альтернатива — плагин check_snmp_storage.pl. У меня исторически сложилось так, что windows-сервера мониторятся через check_disk_snmp.pl, а unix-сервера — через check_snmp_storage.pl. Он использует ту же 25 ветку oid и тоже позволяет мониторить дисковые разделы по имени (точке монтирования). Потому что всем, кроме админа самого сервера, совершенно не интересно, что именно у него прицеплено в точку /data, или /var, или /opt, или /mnt/disk0101019084. Важно — сколько там места всего, сколько занято, сколько свободно.
Вышеупомянутый же check_snmp_load.pl умеет мониторить cpu на unix-серверах, check_tpc и check_udp — доступность сетевых портов.
Кроме того, у нагиоса есть полезный плагин check_by_ssh. Суть его в том, что он устанавливает ssh-соединение с хостом и запускает там заданную программу. Программа должна отвечать в формате nagios (код завершения 0 — успешно, 1 — warning, 2 — critical, 3 — unknown) и может выполнять любые угодные вам (и админу того сервера) проверки.
На почтовых серверах бывает полезно мониторить состояние почтовой очереди. Для этого можно использовать check_by_ssh, но так исторически сложилось, что я использую расширение snmp (напоминаю, у меня старая, обросшая ракушками система мониторинга — но это и хорошо, можно на живых примерах показать разные способы получить один и тот же результат). Плюс подхода «без ssh» очевиден — сервер мониторинга не имеет возможности подключиться к исследуемому серверу по ssh и не создает дырку в безопасности.
Итак, расширяем snmp. На исследуемом сервер в snmpd.conf пишем строчку вида
extend mailq /root/getmailq.sh
, где extend — команда, mailq — название ветки, ls -al /var/spool/mqueue | wc -l
(эти конкретные сервера — freebsd, у linux или других unix расположение очереди может отличаться).
На сервере мониторинга
#!/usr/bin/bash
# (C) by Smithson Inc, 2006
SNMP=/usr/bin/snmpget
HOST=$1
PASS=$2
WARN=$3
CRIT=$4
if [ -z $HOST ]; then
echo Usage $0 HOST [SNMPCOMMUNITY [WARN [CRIT]]]
exit 3
fi
if [ -z $PASS ]; then
PASS=public
fi
if [ -z $WARN ]; then
WARN=1000
fi
if [ -z $CRIT ]; then
CRIT=5000
fi
Q=`$SNMP -v 2c -c $PASS $HOST NET-SNMP-EXTEND-MIB::nsExtendOutLine.\"mailq\".1 | awk '{ print $4}'`
if [ $Q -ge $CRIT ]; then
echo "CRITICAL: mailq is $Q"
exit 2
fi
if [ $Q -ge $WARN ]; then
echo "WARNING: mailq is $Q"
exit 1
fi
Собственно магия кроется в запросе NET-SNMP-EXTEND-MIB::nsExtendOutLine.\«mailq\».1 — это мы читаем, что нам отдает скрипт с наблюдаемого сервера.
Ну и стандартное для нагиоса описание команды
define command{
command_name check-snmp-mailq
command_line /path-to-scripts/snmp_extend_mailq.sh $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$
}
Это хорошая альтернатива check_by_ssh с одной оговоркой. snmpd на сервере по-умолчанию работает от рута. А check_by_ssh может работать от другого юзера, с меньшими полномочиями. Решать вам.
Теперь о dns. Очень часто мониторинг dns сводят к банальному check_udp!53. Это очень блаародно, но малоинформативно. Сервер может работать, но не разрешать имена. Сервер может работать и быть корневым для ваших имен, но регистрация вашего домена могла протухнуть. Ничего этого вы из проверки доступности порта не увидите. Поэтому пара скриптов проверки ДНС.
Первый скрипт позволяет мониторить ваш(и) домен(ы) и не проспать необходимость их продления. Даже если домен вам продлевает провайдер автоматом, проконтролировать этот факт всегда полезно.
#!/usr/bin/perl
#
# (C) Smithson Inc, 2013
#
use HTTP::Date;
my $domain = $ARGV[0];
if (!(defined($domain))) {
print "Usage: $0 domain.name\n\n";
exit(-1);
}
$DD=`whois $domain | grep paid-till`;
$DAY = 86400;
$WARNING = $ARGV[1] ? $ARGV[1] : 36;
$CRITICAL = $ARGV[2] ? $ARGV[2] : 10;
if ($DD =~ /(\d\d\d\d\.\d\d\.\d\d)/) {
my $dx = str2timestamp($1);
my $dz = time();
print "Whois $domain end date: $1\n";
if ($dz > ($dx-($CRITICAL*$DAY))) { exit(2); }
if ($dz > ($dx-($WARNING*$DAY))) { exit(1); }
exit(0);
} else {
print "Error whois answer: $DD\n";
exit(-1);
}
sub str2timestamp {
my $time = shift;
$time =~ s/(\d+)\.(\d+)\.(\d+)/$1-$2-$3/;
my $timenix = str2time( $time );
return $timenix;
}
Используется он банально
./check-domaintime.pl smithson.ru [warning [critical]]
По-умолчанию 36 дней до окончания срока регистрации — warning, 10 дней — critical.
Второй скрипт служит для проверки работоспособности dns-сервера
#!/usr/local/bin/perl
#
# (C) Smithson Inc, 2015
#
#use strict;
use lib "/usr/local/libexec/nagios";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use vars qw($PROGNAME);
use Getopt::Long;
use Time::gmtime;
use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H $volname $opt_mode $mode);
$PROGNAME = `basename $0`;
Getopt::Long::Configure('bundling');
GetOptions
("V" => \$opt_V, "version" => \$opt_V,
"h" => \$opt_h, "help" => \$opt_h,
"a=s" => \$opt_addr, "addr=s" => \$opt_addr,
"H=s" => \$opt_H, "hostname=s" => \$opt_H);
if ($opt_V) {
print_revision($PROGNAME,''); #'
exit $ERRORS{'OK'};
}
if ($opt_h) {
print_help();
exit $ERRORS{'OK'};
}
$opt_H = shift unless ($opt_H);
my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
if (!(defined($host))) { print_usage(); exit $ERRORS{'ERROR'}; };
my $addr = 0;
($opt_addr) || ($opt_addr = shift) || ($opt_addr = 'www.slavneft.ru');
$addr = $opt_addr;
$code = $ERRORS{'OK'};
my $look = '/usr/local/bin/nslookup';
my $n = getdns($host, $addr);
print "$n\n";
exit ($code);
# ================================================================
sub getdns {
my $ip = shift, $s, $ret='';
my $addr = shift;
$s = "$look $addr $ip";
my $s = `$s`;
my @D = split(/\n/, $s);
foreach my $i (@D) {
if ($i =~ /server can.t find/) { $code = $ERRORS{'WARNING'}; }
if ($i =~ /no servers could be reached/) { $code = $ERRORS{'ERROR'}; }
$ret = $ret.' '.$i;
}
return $ret;
}
# ================================================================
sub print_usage () {
print "Usage: $PROGNAME -H <host> [-a] address\n";
}
# ================================================================
sub print_help () {
print_revision($PROGNAME,'');
print "Copyright (c) Smithson Inc, 2015 \n";
print "\n";
print_usage();
print "\n";
print "<address> Address for conversion to ip \n\n";
support();
};
# ================================================================
Этот скрипт можно использовать двумя способами. Первый — проверка через ваш сервер доступность нужных вам адресов и вообще работы dns. Например, так:
check-dns.pl ip-вашего-сервера google.com
Если ваш сервер резолвит google.com — то dns на нём работает. В случае, если нет доступа в инет, резолвинг не сработает, но это вы увидите по другим проверкам (пинги gateway провайдера, пинг того же 8.8.8.8).
Так же вы можете проверять, что резолвятся нужные вам внутренние имена (например, AD становится плохо, если её собственный dns не распознает имена).
Второй способ — проверка через гарантированно работающий dns ваших имен, которые должны быть доступны из интернета.
check-dns.pl 8.8.8.8 smithson.ru
Если ответ есть — ваши имена из инета доступны (с оговоркой о доступности Интернет в данный момент для вашей системы мониторинга).
Мониторинг Netware
Да-да, я знаю, некрофилия фу, но даже сегодня у меня из примерно 200 серверов в системе есть 2 (два!) Netware. Оба в далеких ДО, настроенные в одна тыща восемьсот затертом году и с тех пор работают, работают и работают. У одного из uptime сегодня 834 дня. Это к слову. Поэтому — мониторинг.
На последней netware 6.5.8 есть snmp. Честно скажу — не знаю, не ел. С версии 4.11 для netware есть программка mrtgext.nlm, которая позволяет мониторить кучу параметров сервера. Вот её-то обычно и используют и для отрисовки статистики сервера через mrtg или rrdtool, ну и для мониторинга через нагиос она вполне годится. К тому же один из этих двух моих NW имеет версию 5.1 (гусары, молчать!).
mrtgext слушает tcp-порт 9999, поэтому не забудьте поставить его на мониторинг. Поскольку Netware — это прежде всего файловый сервер, то нам интереснее всего, что происходит с томами. Для это есть скриптик:
#! /usr/local/bin/perl
#
# (C) Smithson Inc
#
#
use strict;
use lib "/usr/local/libexec/nagios";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use vars qw($PROGNAME);
use Getopt::Long;
use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H $volname $opt_prefix $prefix);
$PROGNAME = `basename $0`;
Getopt::Long::Configure('bundling');
GetOptions
("V" => \$opt_V, "version" => \$opt_V,
"h" => \$opt_h, "help" => \$opt_h,
"v=s" => \$volname, "volname" => \$volname,
"w=s" => \$opt_w, "warning=s" => \$opt_w,
"c=s" => \$opt_c, "critical=s" => \$opt_c,
"p=s" => \$opt_prefix, "prefix=s" => \$opt_prefix,
"H=s" => \$opt_H, "hostname=s" => \$opt_H);
if ($opt_V) {
print_revision($PROGNAME,''); #'
exit $ERRORS{'OK'};
}
if ($opt_h) {
print_help();
exit $ERRORS{'OK'};
}
$opt_H = shift unless ($opt_H);
my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
if (!(defined($host))) { print_usage(); exit $ERRORS{'ERROR'}; };
($opt_c) || ($opt_c = shift) || ($opt_c = 92);
my $critical = $1 if ($opt_c =~ /([0-9]+)/);
($opt_w) || ($opt_w = shift) || ($opt_w = 80);
my $warning = $1 if ($opt_w =~ /([0-9]+)/);
($volname) || ($volname = shift) || ($volname = 'SYS');
my $vname = $volname;
my $ppp = $opt_prefix;
my $q = "/usr/local/sbin/nwstat.pl $host V".$ppp."U$vname V".$ppp."S$vname";
#print "$host, $vname, $critical, $warning ($ppp = $opt_prefix) \n";
#print "$q \n";
my $res = `$q`;
my @aar=split(/\n/, $res);
my $size = $aar[1];
my $used = $aar[0];
if (($size < 1) || ($used < 0)) { exit $ERRORS{'ERROR'}; }
#print "Size: $size, used: $used\n";
my $percent = ($used/$size)*100;
if ($percent > 100) { exit $ERRORS{'ERROR'}; }
printf "Used: %.2f\%\n", $percent;
if ($percent > $critical) { exit $ERRORS{'CRITICAL'}; } # Critical!
if ($percent > $warning) { exit $ERRORS{'WARNING'}; } # Warning!
exit $ERRORS{'OK'}; # Okay
sub print_usage () {
print "Usage: $PROGNAME -H <host> [-v <volumename>] [-w <warn>] [-c <crit>] [-p <prefix>]\n";
}
sub print_help () {
print_revision($PROGNAME,'');
print "Copyright (c) Smithson Inc, 2011\n";
print "\n";
print_usage();
print "\n";
print "<warn> = Signal strength at which a warning message will be generated.\n";
print "<crit> = Signal strength at which a critical message will be generated.\n";
print "<prefix> = Special signal for nwstat, calculated size, free and used as KBytes (value K) or Bytes (value nothing).\n\n";
support();
}
Он, в свою очередь, использует скрипт nwstat.pl, когда-то шедщий в комплекте mrtgext. Идет ли он сейчас — не знаю, поэтому выложу его сюда.
#!/usr/local/bin/perl
#########################################################
# Netware Server Stat Extension to MRTG #
# Client Access #
# #
# This is the "client" portion of the Netware Server #
# stats extension for MRTG. This will open up a #
# connection to the specified server and get the #
# information that you specify. #
# #
#########################################################
# Written by James Drews (drews@engr.wisc.edu) on #
# Version 1.46 #
# URL: #
#http://forge.novell.com/modules/xfmod/project/?mrtgext #
#########################################################
# #
# Feel free to contact me with any questions/comments/ #
# and such. #
# #
#########################################################
# This program is freeware. *NO* warranty is expressed,#
# implied, nor granted to you in any way. Use of this #
# program is at your own risk. Your mileage may vary. #
# This program was packed by weight, not by volume. #
# Some settling may have occurred during shipment. #
#########################################################
#########################################################
# Command Line Usage #
# nwstat.pl host option1 option2 #
# where host is the DNS name of the server to query #
# and option1 and option2 are any combination of the #
# following (case is not important): #
# UTIL1 : 1 minute average CPU utilization #
# UTIL5 : 5 minute average CPU utilization #
# UTIL15 : 15 minute average CPU Utilization #
# LICENSE : Connection License Count #
# CONNECT : number currently licensed connections #
# CONNMAX : Max number licensed connections used #
# CONNPEAK : Peak Connections #
# : (netware 3 = error (-1) ) #
# : (netware 4 = number connections #
# : allocated) #
# NAME : Server's name #
# UPTIME : Time that the server is operational #
# VS<vol> : size of the volume <vol> in bytes #
# VF<vol> : bytes free on <vol> #
# VU<vol> : bytes used on <vol> #
# VKS<vol> : size of the volume <vol> in kbytes #
# VKF<vol> : kbytes free on <vol> #
# VKU<vol> : kbytes used on <vol> #
# VP<vol> : bytes of purgable files on <vol> #
# VKP<vol> : kbytes of purgable files on <vol> #
# VNP<vol> : bytes of not-yet-purgable files #
# VKNP<vol> : kbytes of not-yet-purgable files #
# ZERO : Returns the value 0 #
# VOLUMES : Returns the list of mounted volumes #
# : each volume name is on a seperate #
# : line. Used by the nlmcfg.pl script #
# S1 : Long Term Cache Hit Percentage #
# S2 : Current number cache buffers #
# S3 : Number of dirty cache buffers #
# S4 : Cache LRU in seconds #
# S5 : Cache LRU in minutes #
# S6 : Dirty cache buffers as percent of tot #
# S7 : Total cache buffers as percent of #
# original #
# S8 : Original number of cache buffers #
# S9 : SAP object Count #
# S9.x : SAP Object count for service x #
# S10 : CPU Count #
# S11 : IS DS Database Open? 1=yes 0=no #
# S12 : Logins enabled? 1=yes 0=no #
# S13 : DS.NLM Version string #
# S14 : MRTGEXT.NLM Version string #
# S15 : Packet receive buffer count #
# S16 : Get Maximum packet receive buffer cnt #
# S17 : Abended thread count (5.x only) #
# S18 : Open file count #
# S19 : OS Version String #
# S20 : Max service processes #
# S21 : Current service processes (5.x only) #
# S22 : Time In Sync To the Network (0=No, #
# 1 = yes) #
# S23:<nlm> : Is <nlm> loaded? (0=no,1=yes) #
# S24:<nlm> : Get <nlm>'s version #
# S25 : Minimum Directory Cache Buffers #
# S26 : Maximum Directory Cache Buffers #
# S27 : Current Directory Cache Buffers #
# #
# Example: To get the server utilization for 5 and 15 #
# minutes on the myserv.mydomain.com. #
# #
# nwstat.pl myserv.mydomain.com UTIL5 UTIL15 #
# #
# Example: To graph the disk space usage on the SYS #
# volume on myserv.mydomain.com. #
# #
# nwstat.pl myserv.mydomain.com VFsys VUsys #
#########################################################
# #
# Other notes: #
# The server side NLM can take ALL the options on the #
# command line at once. However, MRTG is written to #
# only graph two variables at a time. Should some #
# ambitious person modify the program to graph more #
# than two items at once, this program can easily be #
# expanded to output more items. #
# #
# The server will stop accepting input at 1023 chars #
# or when it gets the first \n character #
# #
# Thanks to Kevin Keyser <kevin-keyser@uiowa.edu> #
# for fixing the problem of loosing the 'W' char from #
# the server name #
#########################################################
# Required for perl5.
use Socket;
($_, $opt1, $opt2) = @ARGV;
if (!$_) {
print "Usage: $0 HOST OPTION1 OPTION2 \n";
print " where host is the DNS name of the server to query\n";
print " and option1 and option2 are any combination of the\n";
print " following (case is not important):\n";
print " UTIL1 : 1 minute average CPU utilization\n";
print " UTIL5 : 5 minute average CPU utilization\n";
print " UTIL15 : 15 minute average CPU Utilization\n";
print " LICENSE : Connection License count\n";
print " CONNECT : number currently licensed connections\n";
print " CONNMAX : max licensed connections used\n";
print " CONNPEAK : Peak Connections\n";
print " : (netware 3 = error (-1) )\n";
print " : (netware 4 = number connections\n";
print " : allocated)\n";
print " VF<vol> : bytes free on <vol>\n";
print " VS<vol> : size in bytes of <vol>\n";
print " VU<vol> : bytes used on <vol>\n";
print " VKF<vol> : kbytes free on <vol>\n";
print " VKS<vol> : size in kbytes of <vol>\n";
print " VKU<vol> : kbytes used on <vol>\n";
print " ZERO : returns a zero (0)\n";
print " S1 : Long Term Cache Hit Percentage\n";
print " S2 : Number of Cache Buffers\n";
print " S3 : Number of Dirty Cache Buffers\n";
print " S4 : Cache LRU in seconds\n";
print " S5 : Cahce LRU in minutes\n";
print "\n Example: To graph the disk space usage on the SYS\n";
print " volume on myserv.mydomain.com.\n\n";
die " $0 myserv.mydomain.com VFsys VUsys\n";
}
if (!$opt2) {
printf "No second option specified. MRTG expects two values\n";
die "Use \"ZERO\" for the second option if you only wnat one value.\n";
}
$hostname = $_;
# if you load the NLM with a different port
# from the default, here is where you change it
$port = 9999;
# Open a socket and get the data
($sockaddr,$there,$response,$tries) = ("Snc4x8");
# On Win95, passing a numeric IP address to inet_aton() is slow, so
# detect this case and use a simple conversion.
chomp ($hostname);
if ($hostname =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)(.*)/ )
{
# $remote_addr = pack('C4',"$1.$2.$3.$4");
$remote_addr = "$1.$2.$3.$4";
} else {
$remote_addr = (gethostbyname($hostname))[4]
|| die (host_not_found_error ($hostname, $?));
}
# my $addr_in = 'S n a4 x8';
# $there = pack($addr_in, AF_INET, $port, $remote_addr);
# Конвертирует имя сервера в бинарную последовательность.
my $iaddr = inet_aton($remote_addr);
# Упаковывает все в понятную функции connect последовательность.
$there = sockaddr_in($port, $iaddr);
$proto = (getprotobyname ('tcp'))[2];
if (!socket(S,AF_INET,SOCK_STREAM,$proto)) { printf "-1\n-1\n\n\n"; die "$0: Fatal Error. $!\n"; }
if (!connect(S,$there)) { printf "-2\n-2\n\n\n"; die "$0: Fatal Error. $!\n"; }
select(S);$|=1;
select(STDOUT);
print S "$opt1 $opt2 uptime name\r\n";
$in = int(<S>);
print "$in\n";
while($line = <S>) {
print "$line";
}
close(S);
Использовать его легко и просто:
define command{
command_name check_nwvolsize
command_line $USER1$/check_nwvolsize -H $HOSTADDRESS$ -w $ARG2$ -c $ARG3$ -v $ARG1$ -p K
}
Для рисования статистики:
HtmlDir: /data/www/admin/mrtg
ImageDir: /data/www/admin/mrtg/images
LogDir: /data/www/admin/mrtg/logs
IconDir: /mrtg/icons
Language: Russian
Options[_]: gauge, noarrow, nopercent, unknaszero
kilo[_]: 1000
PageTop[^]: <b><<<<a href=index_nw6.html>To Index Page</b></a><br><br>
<table width=100% cellspacing=0 cellpadding=5 border=1 bgcolor=#dedede align=center>
<tr><td><center><H4>
PageTop[$]: </td></tr></table>
# ------------------- Common Parameters ------------------
Target[nw6_cpu]: `/usr/local/sbin/nwstat.pl 192.168.2.4 util5 util15`
ShortLegend[nw6_cpu]: %
YLegend[nw6_cpu]: CPU Util (%)
LegendI[nw6_cpu]: 5 minute average CPU utilization
LegendO[nw6_cpu]: 15 minute average CPU utilization
MaxBytes[nw6_cpu]: 100
Title[nw6_cpu]: CPU Utilization Analysis for Server NW6
PageTop[nw6_cpu]: CPU Utilization Analysis for Server NW6 </H4></center>
Target[nw6_conn]: `/usr/local/sbin/nwstat.pl 192.168.2.4 connect s18`
MaxBytes[nw6_conn]: 140000
ShortLegend[nw6_conn]:
YLegend[nw6_conn]: Connections & Open files
LegendI[nw6_conn]: Number currently licenzed connections
LegendO[nw6_conn]: Open files
Title[nw6_conn]: Connection & Open Files for Server NW6
PageTop[nw6_conn]: Connection & Open Files for Server NW6 </H4></center>
# s8 = Original number of cache buffers
# s2 = Current number cache buffers
Target[nw6_s2]: `/usr/local/sbin/nwstat.pl 192.168.2.4 s2 s8`
MaxBytes[nw6_s2]: 2000000000
ShortLegend[nw6_s2]:
YLegend[nw6_s2]: Cache Buffers
LegendI[nw6_s2]: Number of Free Cache Buffers
LegendO[nw6_s2]: Number of Total Cache Buffers
Title[nw6_s2]: Number of Cache Buffers for Server NW6
PageTop[nw6_s2]: Number of Cache Buffers for Server NW6 </H4></center>
# s20 = Max service processes
# s21 = Current service processes
Target[nw6_proc]: `/usr/local/sbin/nwstat.pl 192.168.2.4 s21 s20`
MaxBytes[nw6_proc]: 2000000
ShortLegend[nw6_proc]:
YLegend[nw6_proc]: Processes
LegendI[nw6_proc]: Current service processes
LegendO[nw6_proc]: Max service processes
Title[nw6_proc]: Service processes analysis for Server NW6
PageTop[nw6_proc]: Service processes analysis for Server NW6 </H4></center>
# s15 = Packet receive buffer count
# s16 = Maximum packet receive buffer count
Target[nw6_packet]: `/usr/local/sbin/nwstat.pl 192.168.2.4 s15 s16`
MaxBytes[nw6_packet]: 2000000
ShortLegend[nw6_packet]:
YLegend[nw6_packet]: Buffers
LegendI[nw6_packet]: Current packet buffers
LegendO[nw6_packet]: Max packet buffers
Title[nw6_packet]: Packet receive buffers count for Server NW6
PageTop[nw6_packet]: Packet receive buffers count for Server NW6 </H4></center>
#---------------------------------------------------------------------------------
# DISKS
#---------------------------------------------------------------------------------
Target[nw6_vol-data]: `/usr/local/sbin/nwstat.pl 192.168.2.4 VKUDATA VKSDATA`
MaxBytes[nw6_vol-data]: 500000000000
kilo[nw6_vol-data]: 1024
kMG[nw6_vol-data]: k,M,G,T,P
ShortLegend[nw6_vol-data]: b
YLegend[nw6_vol-data]: Disk space
LegendI[nw6_vol-data]: Kbytes used on volume DATA
LegendO[nw6_vol-data]: Size of volume DATA in Kbytes
Title[nw6_vol-data]: Volume DATA statistics for server NW6
PageTop[nw6_vol-data]: Volume DATA statistics for Server NW6 </H4></center>
Target[nw6_pur_vol-data]: `/usr/local/sbin/nwstat.pl 192.168.2.4 VKPDATA VKNPDATA`
MaxBytes[nw6_pur_vol-data]: 1000000000000
kilo[nw6_pur_vol-data]: 1024
kMG[nw6_pur_vol-data]: k,M,G,T,P
ShortLegend[nw6_pur_vol-data]: b
YLegend[nw6_pur_vol-data]: Purgable files
LegendI[nw6_pur_vol-data]: Kbytes of purgable files on volume DATA
LegendO[nw6_pur_vol-data]: Kbytes of not-yet-purgable files on volume DATA
Title[nw6_pur_vol-data]: Volume DATA purgable files statistics for server NW6
PageTop[nw6_pur_vol-data]: Volume DATA purgable files statistics for Server NW6 </H4></center>
Target[nw6_vol-sys]: `/usr/local/sbin/nwstat.pl 192.168.2.4 VKUSYS VKSSYS`
MaxBytes[nw6_vol-sys]: 500000000000
kilo[nw6_vol-sys]: 1024
kMG[nw6_vol-sys]: k,M,G,T,P
ShortLegend[nw6_vol-sys]: b
YLegend[nw6_vol-sys]: Disk space
LegendI[nw6_vol-sys]: Kbytes used on volume SYS
LegendO[nw6_vol-sys]: Size of volume SYS in Kbytes
Title[nw6_vol-sys]: Volume SYS statistics for server NW6
PageTop[nw6_vol-sys]: Volume SYS statistics for Server NW6 </H4></center>
Из него понятно, как можно мониторить процессор, ОЗУ, буфера на Netware-сервере через mrtgext, если это кому-нибудь еще надо.
Мониторинг Novell (уже не, но не суть) OES
.OES — это Open Enterprise Server. В основе OES лежит SUSE Linux, поэтому базовый мониторинг тут те же, что и для linux, а вот как мониторить дополнительные сервисы сейчас опишу.
Опять же на первом месте будет мониторинг томов:
#!/usr/local/bin/perl
#
# (C) Smithson Inc
#
#
#use strict;
use lib "/usr/local/libexec/nagios";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use vars qw($PROGNAME);
use Getopt::Long;
use Time::gmtime;
use vars qw($opt_V $opt_h $verbose $opt_w $opt_c $opt_H $volname $opt_mode $mode);
$PROGNAME = `basename $0`;
Getopt::Long::Configure('bundling');
GetOptions
("V" => \$opt_V, "version" => \$opt_V,
"h" => \$opt_h, "help" => \$opt_h,
"v=s" => \$volname, "volname" => \$volname,
"w=s" => \$opt_w, "warning=s" => \$opt_w,
"c=s" => \$opt_c, "critical=s" => \$opt_c,
"m=s" => \$opt_mode, "mode=s" => \$opt_mode,
"H=s" => \$opt_H, "hostname=s" => \$opt_H);
if ($opt_V) {
print_revision($PROGNAME,''); #'
exit $ERRORS{'OK'};
}
if ($opt_h) {
print_help();
exit $ERRORS{'OK'};
}
$opt_H = shift unless ($opt_H);
my $host = $1 if ($opt_H =~ m/^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|[a-zA-Z][-a-zA-Z0]+(\.[a-zA-Z][-a-zA-Z0]+)*)$/);
if (!(defined($host))) { print_usage(); exit $ERRORS{'ERROR'}; };
($opt_c) || ($opt_c = shift) || ($opt_c = 95);
my $critical = $1 if ($opt_c =~ /([0-9]+)/);
($opt_w) || ($opt_w = shift) || ($opt_w = 90);
my $warning = $1 if ($opt_w =~ /([0-9]+)/);
($volname) || ($volname = shift) || ($volname = 'SYS');
my $vname = $volname;
my $mode = 0;
($opt_mode) || ($opt_mode = shift) || ($opt_mode = 'nagios');
if ($opt_mode =~ /mrtg/i) { $mode = 1; }
my $servname = $host;
my $uptime = '';
my $community = 'ISOlanf';
my $SNMP = "/usr/local/bin/snmpget -v 2c -c $community";
my $snmpwalk = "/usr/local/bin/snmpwalk -v 2c -c $community";
my $OID_NAME = 'SNMPv2-MIB::sysName.0';
my $OID_UPTIME = '.1.3.6.1.2.1.1.3.0';
my $OID_SIZE = 'HOST-RESOURCES-MIB::hrStorageSize';
my $OID_USED = 'HOST-RESOURCES-MIB::hrStorageUsed';
my $OID_DESC = 'HOST-RESOURCES-MIB::hrStorageDescr';
my $pool = '.pools/';
my $n=getvol($host, $vname);
if ($n == 0) { exit $ERRORS{'UNKNOWN'}; }
my $percent = getInfo($host, $n);
if ($mode == 0) { #nagios
if ($percent > 100) { exit $ERRORS{'ERROR'}; }
printf "Used: %.2f\%\n", $percent;
if (($percent > $critical) || ($percent == 0)) { exit $ERRORS{'CRITICAL'}; } # Critical!
if ($percent > $warning) { exit $ERRORS{'WARNING'}; } # Warning!
exit $ERRORS{'OK'}; # Okay
};
if ($mode == 1) { # mrtg
print $percent;
exit (0);
}
# ================================================================
sub getvol {
my $ip = shift;
my $v = shift;
my $ret = 0;
my $seek = $pool.$v;
my @n = getDesc($ip);
foreach $l (@n) {
if ($l =~ /$OID_DESC\.(\d+).+$seek/i) {
return $1;
}
};
return $ret;
}
# ================================================================
sub getInfo {
my $ip = shift;
my $n = shift;
my $ret = '';
$servname = getSNMPdata($ip, $OID_NAME);
my $size = getSNMPdata($ip, $OID_SIZE.'.'.$n);
my $used = getSNMPdata($ip, $OID_USED.'.'.$n);
if ($size < 1) { return ''; }
$ret = ($used/$size)*100;
if ($mode == 1) {
$used = $used*4;
$size = $size*4;
$ret = "$used\n$size\n$uptime\n$servname\n";
}
return $ret;
}
# ================================================================
sub getSNMPdata {
my $ip = shift;
my $snmpquery = shift;
my $q, $dat;
$q = "$SNMP $ip $snmpquery | awk '{print \$4}'";
$dat = `$q`;
chomp $dat;
if (length($dat) < 1) {
return 'U';
}
return $dat;
}
# ================================================================
sub getSNMPstring {
my $ip = shift;
my $snmpquery = shift;
my $q, $dat;
$q = "$SNMP $ip $snmpquery";
$dat = `$q`;
chomp $dat;
if (length($dat) < 1) {
return '';
}
if ($dat =~ /= STRING:\ (.+)/) { $dat = $1 };
return $dat;
}
# ================================================================
sub getDesc {
my $ip = shift;
my @ret = '';
my $q = "$snmpwalk $ip $OID_DESC";
@ret = `$q`;
return @ret;
};
# ================================================================
sub print_usage () {
print "Usage: $PROGNAME -H <host> [-v <volumename>] [-w <warn>] [-c <crit>] [-m <mode>]\n";
}
# ================================================================
sub print_help () {
print_revision($PROGNAME,'');
print "Copyright (c) Smithson Inc, 2013 \n";
print "\n";
print_usage();
print "\n";
print "<warn> = Signal strength at which a warning message will be generated.\n";
print "<crit> = Signal strength at which a critical message will be generated.\n";
print "<mode> = Used mode - nagios -> return percents of volume used, mrtg -> return used and max size of volume for mrtg\nBy default use 'nagios'\n\n";
support();
};
# ================================================================
Скрипт этот у меня универсальный для nagios и для mrtg, поэтому с параметром -m mrtg он выдает циферки размера (занято и всего) тома, как их ждет mrtg, а без оного или с параметром -m nagios выдает ответ, типичный для плагина nagios.
В качестве параметров он принимает имя или ip сервера и имя тома. Тома ищутся в списке смонтированных, точки монтирования .pools/ИМЯТОМА (технические для OES) игнорируются. Если том не найден, возвращается размер 0 и ситуация CRITICAL (у нас много «внешних» — fc или iscsi — томов и надо ловить случаи их отпадения).
По-умолчанию анализируется том SYS (тяжкое наследие Netware, есть у каждого OES-сервера, но совершенно не нужен и не интересен).
Используется в nagios обычным образом
define command{
command_name check_oesvolsize
command_line $USER1$/get-voldata.pl -H $HOSTADDRESS$ -v $ARG1$ -w $ARG2$ -c $ARG3$
}
в mrtg так:
`/data/rrdtool/oes/get-voldata.pl -H ip-сервера -v ИМЯТОМА -m mrtg`
Теперь о сервисе печати. Принтеры можно мониторить самостоятельно, но если у вас iPrint, то интересно мониторить принтеры «с точки зрения сервера». И для этого есть скриптик:
#!/usr/bin/perl -w
#
# @File check_iprinters.pl
# @Author dbenjamin
# @Created Aug 4, 2015 2:59:02 PM
# Licence : GPL - http://www.gnu.org/licenses/lgpl-3.0.html
#
use strict;
use LWP::Simple;
use HTML::TreeBuilder;
use Getopt::Long;
my $nagios_plugins_utils =
# "/usr/lib/nagios/plugins/utils.pm"; #used to test for the library
"/usr/local/libexec/nagios/utils.pm"; #used to test for the library
die "\nLooking for nagios utils.pm at $nagios_plugins_utils"
unless ( -e $nagios_plugins_utils );
use lib "/usr/local/libexec/nagios"; #use just the path here
use utils qw(%ERRORS $TIMEOUT);
my ( $opt_h, $opt_I, $opt_Q, $opt_v, $opt_P, $opt_V );
my ( $printer_state, $accepting_jobs, $jobs_scheduled );
my $i = 0; #iteration holder
$opt_P = '631';
alarm($TIMEOUT);
sub print_version {
print "File: check_iprinters.pl\n";
print "Author: dbenjamin\n";
print "Created: Aug 4, 2015\n";
print "Release: 0.0.1\n";
print "Tested against Novell iPrint Server 6.7.0.20150629-0.6.6, ";
print "running on SLES 11, SP3 with OES 11, SP2.\n";
exit $ERRORS{'UNKNOWN'};
}
sub print_exit {
print
"Usage: $0 -I <host address> -Q <queue name> [-P <port> default=631] [-v enable verbose] [--version]\n\n";
exit $ERRORS{'UNKNOWN'};
}
sub print_verbose {
print "Printer State: $printer_state\n";
print "Printer is Accepting Jobs: $accepting_jobs\n";
print "Jobs Scheduled: $jobs_scheduled\n";
}
GetOptions(
"version" => \$opt_V,
"h" => \$opt_h,
"help" => \$opt_h,
"I=s" => \$opt_I,
"Q=s" => \$opt_Q,
"P:s" => \$opt_P,
"v" => \$opt_v,
) or print_exit;
if ($opt_V) {
print_version;
}
if ($opt_h) {
print_exit;
}
if ( !$opt_I ) {
print "No Host address specified\n";
print_exit;
}
if ( !$opt_Q ) {
print "No Queue name specified\n";
print_exit;
}
if ( ( $opt_I eq '' ) or ( $opt_Q eq '' ) ) { print_exit; }
my $tree = new HTML::TreeBuilder->new;
my $url = "http://$opt_I:$opt_P/ipp/$opt_Q";
my $result = get($url);
die "\nCouldn't get $url" unless defined $result;
$tree->parse($result);
my @tbrows = $tree->look_down( '_tag', 'TR' );
die "No response, check the URL for errors: $url\n\n" unless @tbrows;
foreach $i ( 2 .. 4 ) {
my @td = $tbrows[$i]->look_down( '_tag', 'TD' );
if ( $i == 2 ) { $printer_state = $td[1]->as_text; }
if ( $i == 3 ) { $accepting_jobs = $td[1]->as_text; }
if ( $i == 4 ) { $jobs_scheduled = $td[1]->as_text; }
}
if ( ( $printer_state =~ /error/i ) & ( $printer_state =~ /empty/i ) ) {
if ($opt_v) { print_verbose }
else { print "$printer_state\n\n"; }
exit $ERRORS{'WARNING'};
}
else {
if ( $printer_state =~ /error/i ) {
if ($opt_v) { print_verbose }
else { print "$printer_state\n\n"; }
exit $ERRORS{'CRITICAL'};
}
}
if ( $opt_v ) { print "jobs=$jobs_scheduled\n"; }
exit $ERRORS{'OK'};
Скрипт не мой, но чертовски полезный. В нагиос его можно использовать так:
define command{
command_name check_iprinter_q
command_line $USER1$/check_iprinters.pl -I $HOSTADDRESS$ -Q $ARG1$ $ARG2$
}
define service{
use generic-service
name iprint_q
host_name iprint
contacts printer-admins
check_period 24x7
max_check_attempts 3
normal_check_interval 10
retry_check_interval 5
notifications_enabled 0
notification_options c,r
notification_interval 60
notification_period workhours
icon_image printer.gif
flap_detection_enabled 0
register 0
}
define service{
use iprint_q
service_description AHO-2430
check_command check_iprinter_q!AHO-2430!-v
}
Когда принтеров у вас несколько десятков (у меня их ближе к сотне), вести такой список непросто, но зато вы сразу видите, где кончилась бумага или картридж, какой принтер уже 40+ дней отключен (у нас 40 дней отключения — порог на снятие принтера) или стоит много дней без бумаги или картриджа. Польза есть.
Фух, много получилось. Пока остановлюсь. Если статья понравится, будет вторая часть — про мониторинг ИБП, Synology, vmware и принтеров, но уже как принтеров, а не как объектов iPrint.
Комментарии (19)
Godless
16.08.2016 22:45+1Прошу, не останавливайтесь. Интересно жешь…
зы: чем таки заббикс не угодил? не холивара ради, а интернса для. И шлете ли смс или как вообще у вас уведомления устроены? Опыт интересен…CentALT
17.08.2016 09:07+1Не автор поста, но отвечу, 10 лет назад альтернативы nagios практически не было, а когда уже мониторится более 4k железок, то переходить на другую систему мониторинга как бы особого смысла уже нет.
SMS рассылаются просто
define contact { contact_name лалала alias лалала service_notification_period 24x7 host_notification_period 24x7 service_notification_options w,u,c,r host_notification_options d,u,r service_notification_commands sms_service host_notification_commands sms_service2 pager 7913лалалал } define command { command_name sms_service2 command_line /usr/bin/send_sms.pl $CONTACTPAGER$ "$HOSTNAME$-$HOSTADDRESS$-$HOSTSTATE$-$LONGDATETIME$" "$HOSTNAME$-$HOSTADDRESS$-$HOSTSTATE$-$LONGDATETIME$-$SERVICEOUTPUT$" }
Код /usr/bin/send_sms.pl написать по вкусу смотря через что будете слать СМС например через gnokii.Godless
17.08.2016 09:50Про альтернативы понял. А про смс я спрашивал не как сделать, а скорее действительно ли нужная штука, или может все таки блаж (исходя из опыта)...
Smithson
17.08.2016 09:55+2Спасибо, вторая часть будет! Может быть даже сегодня :)
Забикс не угодил внешним видом и настройкой.
Nagios у нас настроен так, что показывает на первом экране при открытии закладку problem — чтобы даже самый сбодуна сотрудник техподдержки смог сразу увидеть, что есть проблема. У забикса так сделать не удалось, простыня вперемешку зеленого с желтым и красным на 10 экранов — неинформативно. Это было давно, подробностей не помню. Ну и настройка забикса была (на мой взгляд) позапутаннее, чем у нагиоса.
смс я шлю примерно так, как описано в ответе выше, вот таким скриптом
sendsms#!/usr/local/bin/bash # # $1 - number of phone # $2 - text. Space must be change to + # DATE=`date "+%Y-%m-%d"` LOGFILE=/data/sms.ru/$DATE.log phone="$1" read text cd /data/sms.ru message="$text" txt=`echo $message | sed -e 's/ /+/g'`. echo "To phone ' $phone ' sending ' $txt '" >>$LOGFILE /usr/local/bin/curl -d "text=$txt" http://sms.ru/sms/send\?api_id=вашidнаsmsru\&to=$phone echo. echo OK
NikiN
17.08.2016 10:19Миграцию на icinga не планируйте?
Smithson
17.08.2016 10:30Смотрел, не увидел плюсов от слова совсем. Всё-таки система мониторинга — это не самоцель, самоцель — быстрый доступный мониторинг. «Не тронь технику — и она не подведет» (с). Потратить несколько дней на то, чтобы повторить уже работающую систему — зачем?
CentALT
17.08.2016 10:47+1Мигрировал, конфиги 1 в 1. Просто обновил пакет и все заработало. Подводных камней не было.
MechanID
17.08.2016 14:27приветствую, расскажите пожалуста по каким причинам или соображениям не используете nrpe демон на unix-серверах?
Smithson
17.08.2016 14:32Добрый день. Ответ «так исторически сложилось» вас устроит? Одно дело поставить на (например) боевой oracle-сервер snmp или даже дать малоправному пользователя ssh, а другое — накатить кучу nagios-плагинов с кучей зависимостей. Основная идея нашего мониторинга — не трогай то, что мониторишь, руками. Смотри издалека.
MechanID
17.08.2016 15:51Полностью устраивает — всегда интересно узнать чужие use-case и точку зрения, временами позволяет взглянуть на собственные задачи и проблемы с новой стороны.
Спасибо за ответ.
varnav
17.08.2016 17:05А разве nagios не был заменён на icinga, которая затем заменена на icinga2?
viiy
18.08.2016 11:51Icinga это форк nagios. Причина отделения — недовольство разработчиков направлением развития Nagios.
Сейчас оба продукта развиваются, причем icinga не ломает совместимость с последним.
viiy
17.08.2016 23:46Интересно, пускай и не популярно сегодня (все переходят на всякие grafana, prometheus и etc)
Расскажите как решаете проблему перегрузки временных пулов в nagios?
Имею ввиду, когда проверок становится настолько много, что заполнялась очередь и шли варнинги что проверка не успевает выполняться с заданным расписанием.
В свое время тоже админил nagios/icinga, и был вынужден часть «активных» проверок переводить в «пассивные»
Т.е использовать по максимуму snmp-traps (гемор с snmptt)
Для части проверок использовал nrpe, там где было приемлемо — nsca_send
Хостов было около 350, проверок уже не помню, в 2 раза больше.
Было много хостов где мониторилась только доступность.Smithson
18.08.2016 09:58Расскажите как решаете проблему перегрузки временных пулов в nagios?
Честно сказать, ни разу не сталкивался за 10 лет. Но у меня есть хосты, у которых даже доступность проверяется раз в 10-30 минут, остальные сервисы еще реже. Далёкие ДО…
И сервер реальный и толстый под это дело стоит (Proliant DL380 G8), и система там freebsd, она сама по себе ресурсы не жрет, как слон банные веники, нагиосу много остаётся.viiy
18.08.2016 11:40Да, тогда понятно, вижу у вас другие требования к кониторингу.
У нас большинство проверок было с интервалом 1 и 5 минут, поэтому часто возникали проблемы и приходилось оптимизировать конфигурацию.
С интервалом 15 минут проверялось только место на диске.
Спасибо, интересно увидеть продолжение!Smithson
18.08.2016 11:55
NikiN
Если бы статья вышла в 2003, вы могли бы замечательно дополнить Мониторинг Windows-серверов с помощью Nagios