Tamkovich.com: Телеком/VoIP блог
Современные технологии: Asterisk, SIP, Kamailio, Linux, Cisco, Linksys
Расширение NET SNMP
6 октября, 2009 by Сергей Тамкович
Мониторинг snmpПо умолчанию, агент NET-SNMP предоставляет доступ к огромному количеству параметров. Здесь и различные счётчики с интерфейсов, и загрузка процессора, памяти и объём с жесткого диска. Пакет lm_sensors добавляет показания различных датчиков — термометры, измерители оборотов и т.д. Зачастую, наибольший интерес представляет мониторинг нестандартного оборудования или программного обеспечения, поддержки для которого в NET SNMP нет.
Самостоятельно расширить NET SNMP можно несколькими способами
Создание сабагента AgentX (AgentX subagent)
Subagent это независимое приложение которое осуществляет обработку специфических параметров и предоставляет их SNMP агенту по протоколу AgentX (RFC 2741). Многие производители программного обеспечения, распространяют сабагент в комплекте со своим ПО, например Sybase предоставляет SQL Server SNMP Subagent вместе со своим сервером БД. Если сабагента нет, его можно создать самому. Проще всего сделать это с помощью библиотеки libnetsnmpagent (AgentX Library). Сгенерировать скелет агента можно с помощью программы mib2c, для этого надо иметь MIB файл, описывающий параметры которые нам предстоит мониторить. В состав пакета net-snmp входит скрипт net-snmp-config. Этот скрипт, запущенный с параметром —compile-subagent, позволяет легко скомпилировать вашу программу-сабагент.
% net-snmp-config --compile-subagent mysubagent nstAgentSubagentObject.c generating the tmporary code file: netsnmptmp.12259.c checking for init_nstAgentSubagentObject in nstAgentSubagentObject.c init_nstAgentSubagentObject(void) running: gcc -Dlinux -I. -I/usr/local/include -o nstAgentSubagentObject netsnmptmp.12259.c nstAgentSubagentObject.c -L/usr/local/lib -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp netsnmptmp.12259.c: In function `main': netsnmptmp.12259.c:26: warning: implicit declaration of function `init_nstAgentSubagentObject' removing the tmporary code file: netsnmptmp.12259.c subagent program nstAgentSubagentObject created
В результате компиляции получится программа mysubagent. Эту программу следует запускать после старта snmpd. Для того что бы включить поддержку протокола AgentX в snmpd.conf следует добавить строку «master agentx». Функционал сабагента, можно вынести в отдельную программу, а можно сделать частью вашей программы, как сделано, например, в Asterisk. Модуль, выполняющий функции сабагента в Asterisk, называется res_snmp.
Создание модуля DLO (Dynamically Loadable Object)
Другой вариант расширения net-snmp — написание модуля, который будет динамически подгружаться во время запуска snmpd. Данный подход имеет свои преимущества и недостатки. К преимуществам можно отнести: доступность всего API snmpd внутри модуля, возможность использовать общие конфигурационные файлы, отсутствие необходимости следить за порядком запуска приложений (сначала snmpd, затем сабагент). Самый явный недостаток — ошибки в модуле могут скомпрометировать весь сервис snmpd.
Модуль DLO это программа, скомпилированная как разделяемый объект (SO). Существует ряд требований, которые должна удовлетворять данная программа. В программе должны присутствовать функции:
void init_nstAgentPluginObject (void); |
и обратная ей
void deinit_nstAgentPluginObject (void); |
Эти функции вызываются автоматически после загрузки и перед выгрузкой модуля. nstAgentPluginObject — это имя загружаемого модуля, будет различаться от модуля к модулю. Загрузить модуль можно двумя способами: через командную строку —
snmpd -f -L -DnstAgentPluginObject,dlmod
Или же с помощью специальной записи в snmpd.conf
dlmod nstAgentPluginObject /path/to/nstAgentPluginObject.so
Здесь второе поле — имя модуля. Для того что бы snmpd мог загрузить модуль, имя модуля должно быть корректным (совпадать с именами функций init_ и deinit_)
Расширение SNMPD с помощью скриптов
Пожалуй, самый распространённый способ представления собственных данных через snmpd — расширение с помощью скриптов. Для подключения скрипта к snmpd, в файл snmpd.conf необходимо добавить следующую строку:
pass .1.3.6.1.4.1.2021.255 /bin/sh /usr/local/bin/passtest
Данная строка состоит из 3х полей. 1 поле — ключевое слово «pass», оно указывает snmpd на то, что все запросы, адресованные к веткам входящим в указанное дерево, передавать внешней программе. 2ое поле позволяет указать дерево, контроль над которым мы передаём. 3е поле, это программа и её параметры. Внешняя программа может быть написана на любом языке — это не имеет никакого значения. Единственное требование, предъявляемое к программе, — возможность принимать параметры из командной строки, и выводить результаты на стандартный вывод в определённом формате. SNMPd передает программе 2 параметра, 1ый может принимать значения «-s» или «-n». Параметр «-s» означает, что никаких действий предпринимать не надо, параметр «-n» говорит о том, что за ним следует запрашиваемый OID. Рассмотрим логику работы и формат вывода на примере shell скрипта passtest, распространяемого вместе с net-snmp.
#!/bin/sh -f PATH=$path:/bin:/usr/bin:/usr/ucb PLACE=".1.3.6.1.4.1.2021.255" REQ="$2" if [ "$1" = "-s" ]; then echo $* >> /tmp/passtest.log exit 0 fi if [ "$1" = "-n" ]; then case "$REQ" in $PLACE) RET=$PLACE.1 ;; $PLACE.1) RET=$PLACE.2.1 ;; $PLACE.2.1) RET=$PLACE.2.2 ;; $PLACE.2.2) RET=$PLACE.3 ;; $PLACE.3) RET=$PLACE.4 ;; $PLACE.4) RET=$PLACE.5 ;; $PLACE.5) RET=$PLACE.6 ;; *) exit 0 ;; esac else case "$REQ" in $PLACE) exit 0 ;; *) RET=$REQ ;; esac fi echo "$RET" case "$RET" in $PLACE.1) echo "string"; echo "life the universe and everything"; exit 0 ;; $PLACE.2.1) echo "integer"; echo "42"; exit 0 ;; $PLACE.2.2) echo "objectid"; echo ".1.3.6.1.4.42.42.42"; exit 0 ;; $PLACE.3) echo "timeticks"; echo "363136200"; exit 0 ;; $PLACE.4) echo "ipaddress"; echo "127.0.0.1" ;; $PLACE.5) echo "counter"; echo "42"; exit 0 ;; $PLACE.6) echo "gauge"; echo "42"; exit 0 ;; *) echo "string"; echo "ack... $RET $REQ"; exit 0 ;; esac |
Пример работы данного скрипта:
# /usr/local/bin/passtest -n .1.3.6.1.4.1.2021.255.1 .1.3.6.1.4.1.2021.255.2.1 integer 42
Вывод скрипта, ожидаемый snmpd, состоит из 3х строк. Первая строка содержит следующий OID, причём она может содержать несуществующий, главное, что бы не зацикливалась. Вторая строка содержит тип возвращаемого значения, в нашем случае это integer (целое число), а всего возможно 7 типов: string, objectid, integer, timeticks, ipaddress, counter и gauge. Третья строка содержит значение, возвращенное для OID указанного при запуске скрипта. Расширение NET-SNMP с помощью внешних программ и директивы pass — самый простой и быстрый способ. Однако не стоит забывать об эффективности, для каждого отдельного OID, SNMPd вызовет указанный скрипт, такой подход может быть неприемлем для высоконагруженных систем.
- Tutorial: Writing a Subagent
- Understanding the sub-agent
- Tutorial: Writing a Dynamically Loadable Object
Мониторинг snmp
Большое спасибо за подсказку — очень помогло в деле написания OID для выдачи занятой памяти (отсуствует по умолчанию).
#linux: /usr/bin/free | /usr/bin/awk ‘{if (FNR==2) print $3}’
#Solaris: /usr/bin/vmstat | /usr/bin/awk ‘{if (NR==3) print $5}’
#linux: /usr/bin/vmstat | /usr/bin/awk ‘{if (NR==3) print $4}
Всегда пожалуйста! Заходите ещё.
спасибо
Тут кто то еще этим занимается? Сейчас пытаюсь разобраться с данной темой но чет на такие подводные камни натыкаюсь(