traphandle的使用
前面一篇博客里提到在snmptrapd.conf文件中配置traphandle 能够接收指定的OID报文信息后,调用相应的处理程序对报文进行相应的处理操作。并且可以在调用的时候给程序传递参数。
具体格式为:
TraphandleOID|default PROGRAM [ARGS ...]
例如:
traphandle .1.3.6.1.4.1.2021.251.1 /root/traptest/test.pl test_param
traphandle使用的简单示例
traphandle DISMAN-EVENT-MIB::mteTriggerFired my_command
如上,表示snmptrapd收到DISMAN-EVENT-MIB::mteTriggerFired 对应的snmptrapd OID的报文信息的时候调用 my_command 命令。
(注:这里使用的OID和snmpd里使用的OID不同,例如上面的OID可以接收proc的进程异常报文信息,但是使用snmpd的OID UCD-SNMP-MIB::prTable 收不到该内容的)
如上图所示,在snmptrapd.conf文件中加入traphandle 选项内容。然后
snmptrapd -C -c /usr/local/share/snmp/snmptrapd.conf -df -Lo
启动snmptrapd
随后再把之前配置好的有进程监控proc的snmpd.conf配置的snmpd服务启动。
如图所示,当snmpd启动的时候,snmptrapd接收到proc的snmp报文信息,同时调用my_command命令。但是my_command是随便取得名字,在系统中并不存在,所以报错。
但是以上验证了了,traphandle在收到指定OID报文后确实会调用指定的其他程序。
Forward 选项的使用
上面一篇博客内容里提到forward可以转发指定的OID 报文信息。从接收到的机器转发到其他机器上。
forward default/OID destination
如图所示,该snmptrapd服务会转发除掉traphandle 已经监控的DISMAN-EVENT-MIB::mteTriggerFired 报文之外的其他报文到192.139.68.1的机器上。
snmptrapd -C -c /usr/local/share/snmp/snmptrapd.conf -df -Lo
启动snmptrapd。
使用snmptrap模拟发送报文
snmptrap -v 2c -cpublic 127.0.0.1 "" .1.3.6.1.4.1.2021.251.1 sysLocation.0 s "test_info"
如图所示,snmptrapd有接收到snmptrap模拟发送的报文,并且做了转发。本地验证的时候并没有多台机器,因此随便指定了一个IP地址。否则可以在另外一台机器上也部署一个snmptrapd服务,可以看到转发过去的snmp报文信息。
简单的snmp报文接收处理程序
上面讲到traphandle 可以接收指定OID的报文后,可以调用指定的程序进行相应的处理。
下面就演示一个简单的snmp处理程序,把接收到的snmp报文信息转储到日志里。
#! /usr/bin/python
#coding=utf-8
import os,sys
def get_trap_info(log_file):
log_obj = open(log_file,'a')
for sysline in sys.stdin:
print sysline
log_obj.write(sysline + '\n')
if __name__ =='__main__':
if len(sys.argv) <2:
print "The param is not correct"
exit()
log_file = sys.argv[1]
get_trap_info(log_file)
如上,当transhandle调用时,python程序会自动读取标准输入里的内容,来获取snmp的报文信息,将报文信息打印到屏幕上并输出到日志里。
(注:transhandle调用程序并不会把snmp的报文内容直接传递给被调用程序,一定需要被调用程序自己去标准输入里读取,不管用什么语言来写这个程序都是一样的)。
如上的脚本只是简单的获取snmp报文的程序,有很多监控代理需要在获取到指定报文信息后作出很多相应的操作,我们都是可以通过定制脚本或其他程序去实现。
Snmpd.conf的高级用法
我们在上一篇博客里提到的snmpd的配置里有proc和disk的监控。具体格式如下:
进程监控
Proc NAME [[MAX] [MIN]]
NAME 是可由”ps-e”查看到的进程。当监控的进程数量小于MIN或者大于MAX时,系统管理对象prErrorFlag将置为1,同时prErrMessage中存储了相关的描述信息。
对于上面的异常,可以注册一个修正命令procfix:
Procfix NAME PROG ARGS
当proc监控的进程异常时,procfix会根据注册配置的修复命令将对应的进程再次拉起。
例如:
Proc httpd
Procfix httpd /etc/rc.d/init.d/httpdrestart
磁盘监控
监控磁盘的使用状况,当磁盘使用空间超过阈值后,将dskErrorFlag置为1,同时dskErrorMsg中存储了相关的错误信息描述。
阈值可以是以kb为单位的绝对值,也可以是百分比。
disk PATH [MINSPACE | MINPERCENT%]
系统负载监控
监控系统1、5、10分钟系统的平均负载。
load MAX1 [MAX5 [MAX15]]
类似的监控还有监控系统的swap空间:
swap MIN
文件大小监控
监控文件大小是否超过阈值.最多支持20个文件的同时监控
file FILE [MAXSIZE]
日志文件监控
监控(日志)文件中指定的正则表达式的字符串是否出现。当日志中出现REGEX匹配的内容时与monitor配合可以触发Trap。
logmatch NAME FILE CYCLETIME REGEX
NAME为自己指定的实例值,在logMatchName对象中可查看到,FILE为监控文件的绝对路径。可以使用诸如date的命令表示的文件名(strftime函数支持的时间格式)。
CYCLETIME是以秒计时的检查周期,REGEX表示正则表达式,正则表达式不要使用引号,最多同时支持250个日志文件监控,如果没有配置,则logMatchTable对象为空。
监控文件时代理需要读取文件中的内容,代理初始化读取全部内容,后续只增量读取变换的文件内容。
logmatch apache-GETs /usr/local/apache/logs/acess.log-%Y-%m-%d 60GET.*HTTP.*
monitor
monitor [OPTIONS] NAME EXPRESSION
定义一个监控的MIB对象,该对象的值满足表达式EXPRESSION时触发一次通告或SET请求。
Extend
extend [MIBOID]NAME PROG ARGS
MIBOID置顶配置信息记录的OID位置,ARGS作为PROG的参数PROG需要使用全路径
Extend可以调用执行很多自定义程序,在自定义程序里对网络连接、内存状态等做监控。
自定义extend程序
监测处于TIME_WAIT的TCP连接的脚本 tcp_time_wait_count.sh
#!/bin/bash
#tcpT = `netstat -an|grep TIME_WAIT |wc -l`
echo `netstat -an|grep TIME_WAIT |wc -l`
监测UDP的数量的脚本:udp_count.sh
#!/bin/bash
udp=`netstat -an|grep udp |wc -l`
udp=`expr $udp - 1`
echo $udp
(注:上面的UDP数量要减到snmp监测本身的udp连接)
监测僵尸进程:defunct_count.sh
僵尸进程在linux系统中产生的原理是,父进程fork出子进程后没有调用wait和waitpid等待子进程结束,而恰好父进程某个时候由于某些原因退出了。由于没有对应的父进程处理子进程的后事,导致子进程的进程描述符仍保留在系统中,占用系统进程号的内核资源,而这些资源时有限的。因此成为了僵尸进程
僵尸进程在系统中的标识为”Z”或”defunct”
#!/bin/bash
Z=`ps -e -o stat |grep -e '^[zZ]' |wc -l`
echo $Z
内存监测: mem_usage.sh
内存监测项一般包括:总的swap,可用的swap,总的物理内存,可用内存,及buffer和Cache。这些内容可以使用free命令来查看和获取。
下面的脚本可以获取物理内存和swap的使用率
#!/bin/bash
mem_all=$(free | awk 'NR==2' | awk '{print $2}')
mem_used=$(free | awk 'NR==2' | awk '{print $3}')
mem_pct=`expr $mem_used \* 100 / $mem_all`
swap_all=$(free | awk 'NR==4' | awk '{print $2}')
swap_used=$(free | awk 'NR==4' | awk '{print $3}')
swap_pct=`expr $swap_used \* 100 / $swap_all`
echo $mem_pct
echo $swap_pct
脚本部署:
如上几个脚本都需要用snmpd来加载和部署才能在snmp里可以查看和使用。
用上面提到的extend即可实现。
首先,把上面几个脚本放到任意指定目录(我放到了/usr/my_workspace/snmp/),然后在snmpd.conf中增加内容,如下:
extend tcp_time_wait_count /usr/my_workspace/snmp/tcp_time_wait_count.sh
extend upd_count /usr/my_workspace/snmp/udp_count.sh
extend defunct_count /usr/my_workspace/snmp/defunct_count.sh
extend mem_usage /usr/my_workspace/snmp/mem_usage.sh
上面步骤做完后,重启snmpd服务,
snmpwalk -v 2c-c public 127.0.0.1 .1.3.6.1.4.1.8072.1.3 即可看到上面脚本的执行结果。
这些脚本的信息将记录在iso.org.dod.internet.private.enterprises.netSnmp.netSnmpObjects.nsExtensions中。
这些内容的OID为1.3.6.1.4.1.8072.1.3。通过snmpwalk可以获取对应的内容。如下:
root@ubuntu:/usr/my_workspace/snmp#snmpwalk -v 2c -c public 127.0.0.1 .1.3.6.1.4.1.8072.1.3
NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0= INTEGER: 4
NET-SNMP-EXTEND-MIB::nsExtendCommand."mem_usage"= STRING: /usr/my_workspace/snmp/mem_usage.sh
NET-SNMP-EXTEND-MIB::nsExtendCommand."upd_count"= STRING: /usr/my_workspace/snmp/udp_count.sh
NET-SNMP-EXTEND-MIB::nsExtendCommand."defunct_count"= STRING: /usr/my_workspace/snmp/defunct_count.sh
NET-SNMP-EXTEND-MIB::nsExtendCommand."tcp_time_wait_count"= STRING: /usr/my_workspace/snmp/tcp_time_wait_count.sh
NET-SNMP-EXTEND-MIB::nsExtendArgs."mem_usage"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendArgs."upd_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendArgs."defunct_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendArgs."tcp_time_wait_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."mem_usage"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."upd_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."defunct_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendInput."tcp_time_wait_count"= STRING:
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."mem_usage"= INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."upd_count"= INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."defunct_count"= INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendCacheTime."tcp_time_wait_count"= INTEGER: 5
NET-SNMP-EXTEND-MIB::nsExtendExecType."mem_usage"= INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendExecType."upd_count"= INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendExecType."defunct_count"= INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendExecType."tcp_time_wait_count"= INTEGER: exec(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."mem_usage"= INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."upd_count"= INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."defunct_count"= INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendRunType."tcp_time_wait_count"= INTEGER: run-on-read(1)
NET-SNMP-EXTEND-MIB::nsExtendStorage."mem_usage"= INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStorage."upd_count"= INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStorage."defunct_count"= INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStorage."tcp_time_wait_count"= INTEGER: permanent(4)
NET-SNMP-EXTEND-MIB::nsExtendStatus."mem_usage"= INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendStatus."upd_count"= INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendStatus."defunct_count"= INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendStatus."tcp_time_wait_count"= INTEGER: active(1)
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."mem_usage"= STRING: 87
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."upd_count"= STRING: 9
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."defunct_count"= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."tcp_time_wait_count"= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."mem_usage"= STRING: 87
0
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."upd_count"= STRING: 9
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."defunct_count"= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutputFull."tcp_time_wait_count"= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."mem_usage"= INTEGER: 2
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."upd_count"= INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."defunct_count"= INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."tcp_time_wait_count"= INTEGER: 1
NET-SNMP-EXTEND-MIB::nsExtendResult."mem_usage"= INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."upd_count"= INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."defunct_count"= INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendResult."tcp_time_wait_count"= INTEGER: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."mem_usage".1= STRING: 87
NET-SNMP-EXTEND-MIB::nsExtendOutLine."mem_usage".2= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."upd_count".1= STRING: 9
NET-SNMP-EXTEND-MIB::nsExtendOutLine."defunct_count".1= STRING: 0
NET-SNMP-EXTEND-MIB::nsExtendOutLine."tcp_time_wait_count".1= STRING: 0
如上,通过extend加载自定义程序,我们能实现很多扩展功能,监测我们需要的内容和数据。