知识点回顾
《网络协议学习-SNMP》 前面写了一篇Snmp协议的知识点文章,今天要利用这些知识点,再加一些shell编程知识点,实现一个利用shell脚本,远程获取某个Agent的CPU,内存和硬盘的使用率。 在网上找了半天,也没啥合适的,干脆自己写一个。
知识点补充
先把常见的OID补充一下,要不都不知道读谁
系统参数(1.3.6.1.2.1.1)
OID | 描述 | 备注 | 请求方式 |
---|
.1.3.6.1.2.1.1.1.0 | 获取系统基本信息 | SysDesc | GET | .1.3.6.1.2.1.1.3.0 | 监控时间 | sysUptime | GET | .1.3.6.1.2.1.1.4.0 | 系统联系人 | sysContact | GET | .1.3.6.1.2.1.1.5.0 | 获取机器名 | SysName | GET | .1.3.6.1.2.1.1.6.0 | 机器坐在位置 | SysLocation | GET | .1.3.6.1.2.1.1.7.0 | 机器提供的服务 | SysService | GET | .1.3.6.1.2.1.25.4.2.1.2 | 系统运行的进程列表 | hrSWRunName | WALK | .1.3.6.1.2.1.25.6.3.1.2 | 系统安装的软件列表 | hrSWInstalledName | WALK |
网络接口(1.3.6.1.2.1.2)
OID | 描述 | 备注 | 请求方式 |
---|
.1.3.6.1.2.1.2.1.0 | 网络接口的数目 | IfNumber | GET | .1.3.6.1.2.1.2.2.1.2 | 网络接口信息描述 | IfDescr | WALK | .1.3.6.1.2.1.2.2.1.3 | 网络接口类型 | IfType | WALK | .1.3.6.1.2.1.2.2.1.4 | 接口发送和接收的最大IP数据报[BYTE] | IfMTU | WALK | .1.3.6.1.2.1.2.2.1.5 | 接口当前带宽[bps] | IfSpeed | WALK | .1.3.6.1.2.1.2.2.1.6 | 接口的物理地址 | IfPhysAddress | WALK | .1.3.6.1.2.1.2.2.1.8 | 接口当前操作状态[up | down] | IfOperStatus | .1.3.6.1.2.1.2.2.1.10 | 接口收到的字节数 | IfInOctet | WALK | .1.3.6.1.2.1.2.2.1.16 | 接口发送的字节数 | IfOutOctet | WALK | .1.3.6.1.2.1.2.2.1.11 | 接口收到的数据包个数 | IfInUcastPkts | WALK | .1.3.6.1.2.1.2.2.1.17 | 接口发送的数据包个数 | IfOutUcastPkts | WALK |
CPU及负载
OID | 描述 | 备注 | 请求方式 |
---|
.1.3.6.1.4.1.2021.11.9.0 | 用户CPU百分比 | ssCpuUser | GET | .1.3.6.1.4.1.2021.11.10.0 | 系统CPU百分比 | ssCpuSystem | GET | .1.3.6.1.4.1.2021.11.11.0 | 空闲CPU百分比 | ssCpuIdle | GET | .1.3.6.1.4.1.2021.11.50.0 | 原始用户CPU使用时间 | ssCpuRawUser | GET | .1.3.6.1.4.1.2021.11.51.0 | 原始nice占用时间 | ssCpuRawNice | GET | .1.3.6.1.4.1.2021.11.52.0 | 原始系统CPU使用时间 | ssCpuRawSystem. | GET | .1.3.6.1.4.1.2021.11.53.0 | 原始CPU空闲时间 | ssCpuRawIdle | GET | .1.3.6.1.2.1.25.3.3.1.2 | CPU的当前负载,N个核就有N个负载 | hrProcessorLoad | WALK | . 1.3.6.1.4.1.2021.11.3.0 | | ssSwapIn | GET | . 1.3.6.1.4.1.2021.11.4.0 | | SsSwapOut | GET | . 1.3.6.1.4.1.2021.11.5.0 | | ssIOSent | GET | . 1.3.6.1.4.1.2021.11.6.0 | | ssIOReceive | GET | . 1.3.6.1.4.1.2021.11.7.0 | | ssSysInterrupts | GET | . 1.3.6.1.4.1.2021.11.8.0 | | ssSysContext | GET | . 1.3.6.1.4.1.2021.11.54.0 | | ssCpuRawWait | GET | . 1.3.6.1.4.1.2021.11.56.0 | | ssCpuRawInterrupt | GET | . 1.3.6.1.4.1.2021.11.57.0 | | ssIORawSent | GET | . 1.3.6.1.4.1.2021.11.58.0 | | ssIORawReceived | GET | . 1.3.6.1.4.1.2021.11.59.0 | | ssRawInterrupts | GET | . 1.3.6.1.4.1.2021.11.60.0 | | ssRawContexts | GET | . 1.3.6.1.4.1.2021.11.61.0 | | ssCpuRawSoftIRQ | GET | . 1.3.6.1.4.1.2021.11.62.0 | | ssRawSwapIn. | GET | . 1.3.6.1.4.1.2021.11.63.0 | | ssRawSwapOut | GET | .1.3.6.1.4.1.2021.10.1.3.1 | | Load5 | GET | .1.3.6.1.4.1.2021.10.1.3.2 | | Load10 | GET | .1.3.6.1.4.1.2021.10.1.3.3 | | Load15 | GET |
内存及磁盘(1.3.6.1.2.1.25)
OID | 描述 | 备注 | 请求方式 |
---|
.1.3.6.1.2.1.25.2.2.0 获取内存大小 | hrMemorySize | GET | | .1.3.6.1.2.1.25.2.3.1.1 | 存储设备编号 | hrStorageIndex | WALK | .1.3.6.1.2.1.25.2.3.1.2 | 存储设备类型 | hrStorageType[OID] | WALK | .1.3.6.1.2.1.25.2.3.1.3 | 存储设备描述 | hrStorageDescr | WALK | .1.3.6.1.2.1.25.2.3.1.4 | 簇的大小 | hrStorageAllocationUnits | WALK | .1.3.6.1.2.1.25.2.3.1.5 | 簇的的数目 | hrStorageSize | WALK | .1.3.6.1.2.1.25.2.3.1.6 | 使用多少,跟总容量相除就是占用率 | hrStorageUsed | WALK | .1.3.6.1.4.1.2021.4.3.0 | Total Swap Size(虚拟内存) | memTotalSwap | GET | .1.3.6.1.4.1.2021.4.4.0 | Available Swap Space | memAvailSwap | GET | .1.3.6.1.4.1.2021.4.5.0 | Total RAM in machine | memTotalReal | GET | .1.3.6.1.4.1.2021.4.6.0 | Total RAM used | memAvailReal | GET | .1.3.6.1.4.1.2021.4.11.0 | Total RAM Free | memTotalFree | GET | .1.3.6.1.4.1.2021.4.13.0 | Total RAM Shared | memShared | GET | .1.3.6.1.4.1.2021.4.14.0 | Total RAM Buffered | memBuffer | GET | .1.3.6.1.4.1.2021.4.15.0 | Total Cached Memory | memCached | GET | .1.3.6.1.4.1.2021.9.1.2 | Path where the disk is mounted | dskPath | WALK | .1.3.6.1.4.1.2021.9.1.3 | Path of the device for the partition | dskDevice | WALK | .1.3.6.1.4.1.2021.9.1.6 | Total size of the disk/partion (kBytes) | dskTotal | WALK | .1.3.6.1.4.1.2021.9.1.7 | Available space on the disk | dskAvail | WALK | .1.3.6.1.4.1.2021.9.1.8 | Used space on the disk | dskUsed | WALK | .1.3.6.1.4.1.2021.9.1.9 | Percentage of space used on disk | dskPercent | WALK | .1.3.6.1.4.1.2021.9.1.10 | Percentage of inodes used on disk | dskPercentNode | WALK |
还有很多,也可以自定义,不过以上这些够运维使用了。
命令分析
读取用到的命令是snmpget和snmpwalk,参数就不细说了,举两个例子就可以了,按照前面的OID,来获取一下空闲的CPU
[root@localhost 41src_2in1]
UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 95
可以看到CPU空闲95%,那么学习过数学的我们,一下子就能算出来使用率了。
获取CPU使用率
那将前面的写法封装成shell的函数即可
cpuu()
{
cpufree=$(snmpget -v $version -c $public $ipaddr .1.3.6.1.4.1.2021.11.11.0 |cut -d ' ' -f4 )
cpuused=$[100-cpufree]
if [ $cpufree -gt 0 ]; then
echo $cpuused"%"
else
echo ""
fi
}
这里就涉及到了shell中的数学计算,通过$[x-y]这种写法,就可以计算一个变量的加减乘除,不过仅限于整数操作。小数的写法下面再介绍
获取内存使用率
思路很简单,先得到空闲内存数,然后得到总的内存数,然后
总内存-空闲内存/总内存
即可得到内存使用率。 这里就涉及到了小数的计算,而且这个数据,必然是小于1的, 先上函数
memu()
{
memfree=$(snmpget -v $version -c $public $ipaddr .1.3.6.1.4.1.2021.4.6.0|cut -d ' ' -f4)
memtotal=$(snmpget -v $version -c $public $ipaddr .1.3.6.1.4.1.2021.4.5.0|cut -d ' ' -f4)
memused=$[memtotal-memfree]
memusage=$(echo "scale=2; $memused / $memtotal" | bc|cut -d '.' -f2)
if [ $memusage -gt 0 ]; then
echo $memusage"%"
else
echo ""
fi
}
这里就用到了小数除法的计算,表达方式就是
结果=$(echo "scale=2; $A/ $B" | bc)
其实就是用了bc这个命令,系统中没有的话,需要安装
yum install bc
应该留是通过文件内容,计算结果。感兴趣的可以研究一下
获取硬盘使用率
这里怕是全网独创了一种写法,因为有时候有了一种思路,就不想再去变通了,为了实现这个思路,可谓是想尽办法。 首先这里试着读了一下总的硬盘大小,失败了
[root@localhost 41src_2in1]
UCD-SNMP-MIB::dskTotal = No Such Instance currently exists at this OID
然后也没有成功解决这个问题,后来又发现了可以读去簇的数目和使用簇的多少
[root@localhost 41src_2in1]
HOST-RESOURCES-MIB::hrStorageUsed.1 = INTEGER: 24010176
HOST-RESOURCES-MIB::hrStorageUsed.3 = INTEGER: 24010176
HOST-RESOURCES-MIB::hrStorageUsed.6 = INTEGER: 5264
HOST-RESOURCES-MIB::hrStorageUsed.7 = INTEGER: 6568376
HOST-RESOURCES-MIB::hrStorageUsed.8 = INTEGER: 733540
HOST-RESOURCES-MIB::hrStorageUsed.10 = INTEGER: 0
HOST-RESOURCES-MIB::hrStorageUsed.35 = INTEGER: 0
HOST-RESOURCES-MIB::hrStorageUsed.37 = INTEGER: 92573
HOST-RESOURCES-MIB::hrStorageUsed.38 = INTEGER: 0
HOST-RESOURCES-MIB::hrStorageUsed.55 = INTEGER: 7819037
HOST-RESOURCES-MIB::hrStorageUsed.60 = INTEGER: 49671
HOST-RESOURCES-MIB::hrStorageUsed.61 = INTEGER: 9096739
HOST-RESOURCES-MIB::hrStorageUsed.65 = INTEGER: 0
[root@localhost 41src_2in1]
HOST-RESOURCES-MIB::hrStorageSize.1 = INTEGER: 65400996
HOST-RESOURCES-MIB::hrStorageSize.3 = INTEGER: 98267296
HOST-RESOURCES-MIB::hrStorageSize.6 = INTEGER: 65400996
HOST-RESOURCES-MIB::hrStorageSize.7 = INTEGER: 6568376
HOST-RESOURCES-MIB::hrStorageSize.8 = INTEGER: 733540
HOST-RESOURCES-MIB::hrStorageSize.10 = INTEGER: 32866300
HOST-RESOURCES-MIB::hrStorageSize.35 = INTEGER: 8175124
HOST-RESOURCES-MIB::hrStorageSize.37 = INTEGER: 8175124
HOST-RESOURCES-MIB::hrStorageSize.38 = INTEGER: 8175124
HOST-RESOURCES-MIB::hrStorageSize.55 = INTEGER: 18341120
HOST-RESOURCES-MIB::hrStorageSize.60 = INTEGER: 257536
HOST-RESOURCES-MIB::hrStorageSize.61 = INTEGER: 949451776
HOST-RESOURCES-MIB::hrStorageSize.65 = INTEGER: 1635024
眼前一亮,这不就可以通过加法,计算出来使用比例了吗,我真是太聪明了 这里还用到了一种列相加的办法,例如一个文件中,有一列数字,那么就可以通过以下的shell方式计算出来
awk '{sum += $1};END {print sum}' /tmp/x.txt
然后总结了写法
snmpwalk -v $version -c $public $ipaddr .1.3.6.1.2.1.25.2.3.1.6 |cut -d ' ' -f4 > /tmp/used.txt
snmpwalk -v $version -c $public $ipaddr .1.3.6.1.2.1.25.2.3.1.5 |cut -d ' ' -f4 > /tmp/all.txt
hdused=$(awk '{sum += $1};END {print sum}' /tmp/used.txt)
hdtotal=$(awk '{sum += $1};END {print sum}' /tmp/all.txt)
hdusage=$(echo "scale=2; $hdused / $hdtotal" | bc|cut -d '.' -f2)
hdusage_new=$(echo -e $hdusage | sed -r 's/0*([0-9])/\1/')
if [ $hdusage_new -gt 0 ]; then
echo $hdusage_new"%"
else
echo ""
fi
满怀欣喜的结算之后,发现不太对,然后就又发现,原来每个簇的大小不一样。
[root@localhost 41src_2in1]
HOST-RESOURCES-MIB::hrStorageAllocationUnits.1 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.3 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.6 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.7 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.8 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.10 = INTEGER: 1024 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.35 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.37 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.38 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.55 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.60 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.61 = INTEGER: 4096 Bytes
HOST-RESOURCES-MIB::hrStorageAllocationUnits.65 = INTEGER: 4096 Bytes
每个部分的大小需要用簇的数量*簇的大小,最终才能相加得到准确大小。 于是得到最终写法
hdu()
{
rm -rf /tmp/used_fin.txt
rm -rf /tmp/all_fin.txt
snmpwalk -v $version -c $public $ipaddr .1.3.6.1.2.1.25.2.3.1.6 |cut -d ' ' -f4 >/tmp/used.txt
snmpwalk -v $version -c $public $ipaddr .1.3.6.1.2.1.25.2.3.1.5 |cut -d ' ' -f4 >/tmp/all.txt
snmpwalk -v $version -c $public $ipaddr .1.3.6.1.2.1.25.2.3.1.4 |cut -d ' ' -f4 >/tmp/size.txt
exec 3</tmp/used.txt
exec 4</tmp/size.txt
while read line1<&3 && read line2<&4
do
echo $[line1*line2] >> /tmp/used_fin.txt
done
exec 3</tmp/all.txt
exec 4</tmp/size.txt
while read line1<&3 && read line2<&4
do
echo $[line1*line2] >> /tmp/all_fin.txt
done
hdused=$(awk '{sum += $1};END {print sum}' /tmp/used_fin.txt)
hdtotal=$(awk '{sum += $1};END {print sum}' /tmp/all_fin.txt)
echo $hdusage_new"bytes"
echo $hdtotal"bytes"
hdusage=$(echo "scale=2; $hdused / $hdtotal" | bc|cut -d '.' -f2)
hdusage_new=$(echo -e $hdusage | sed -r 's/0*([0-9])/\1/')
if [ $hdusage_new -gt 0 ]; then
echo $hdusage_new"%"
else
echo ""
fi
}
这里又有一个知识点,就是同时操作两个文件的每一行进行乘法。仔细阅读以下吧。
完整脚本
《下载地址》 使用例子 脚本名称 获取部分 IP地址 snmp版本 COMMUNITY 例如 分别是,硬盘,CPU和内存的使用率
[root@localhost 41src_2in1]
2%
[root@localhost 41src_2in1]
2%
[root@localhost 41src_2in1]
36%
结束语
一个简单的需求,其实也会包含很多个小的知识点,多点耐心,各个击破,最终肯定能解决问题。 今天在群里见到一个悲伤的故事
可怜的小孩…… 真正和孩子相处的方法,我觉得还是需要这样 父母与孩子,还是要共情,而不是一味的教育。 哎,这点表扬我夫人,她做的比我好多了。 我得改正一下。
|