21.7. 使用 Net-SNMP 监控性能
红帽企业 Linux 7 包含 Net-SNMP 软件 套件,其中包括灵活且可扩展的 简单网络管理协议 (SNMP)代理。此代理及其相关实用程序可用于提供从大量系统到支持 SNMP
协议轮询的各种工具的性能数据。
本节介绍将 Net-SNMP 代理配置为通过网络安全地提供性能数据,使用 SNMP 协议检索数据,以及扩展 SNMP 代理以提供自定义性能指标。
21.7.1. 安装 Net-SNMP
Net-SNMP 软件套件可作为 Red Hat Enterprise Linux 软件分发包中的一组 RPM 软件包使用。表 21.2 “可用的 Net-SNMP 软件包” 总结了每个软件包及其内容。
软件包 | Provides |
---|---|
net-snmp | SNMP 代理后台程序和文档.导出性能数据时需要此软件包。 |
net-snmp-libs |
nets |
net-snmp-utils |
SNMP 客户端,如 |
net-snmp-perl |
|
net-snmp-python | 适用于 Python 的 SNMP 客户端库。请注意,这个软件包由可选频道提供。有关红帽附加频道的详情,请查看 第 9.5.7 节 “添加 Optional 和 Supplementary 存储库”。 |
要安装这些软件包,请使用以下格式的 yum
命令:
yum
install
package…
例如,要安装本节其余部分中使用的 SNMP 代理守护进程和 SNMP 客户端,以 root
用户身份在 shell 提示符后输入以下内容:
~]# yum install net-snmp net-snmp-libs net-snmp-utils
有关如何在 Red Hat Enterprise Linux 中安装新软件包的详情请参考 第 9.2.4 节 “安装软件包”。
21.7.2. 运行 Net-SNMP 守护进程
net-snmp 软件包包含 snmpd
,即 SNMP 代理守护进程。本节介绍如何启动、停止和重新启动 snmpd
服务。有关在 Red Hat Enterprise Linux 7 中管理系统服务的详情请参考 第 10 章 使用 systemd 管理服务。
21.7.2.1. 启动服务
要在当前会话中运行 snmpd
服务,以 root
用户身份在 shell 提示符后输入以下内容:
systemctl start snmpd.service
要将服务配置为在引导时自动启动,请使用以下命令:
systemctl enable snmpd.service
21.7.2.2. 停止服务
要停止正在运行的 snmpd
服务,以 root
用户身份在 shell 提示符后输入以下内容:
systemctl stop snmpd.service
要禁用在引导时启动服务,请使用以下命令:
systemctl disable snmpd.service
21.7.2.3. 重启服务
要重启正在运行的 snmpd
服务,在 shell 提示符后输入以下内容:
systemctl restart snmpd.service
此命令将停止服务,并快速启动该服务。要在不停止服务的情况下重新载入配置,请运行以下命令:
systemctl reload snmpd.service
这会导致正在运行的 snmpd
服务重新加载其配置。
21.7.3. 配置 Net-SNMP
要更改 Net-SNMP 代理守护进程配置,请编辑 /etc/snmp/snmpd.conf
配置文件。Red Hat Enterprise Linux 7 中包含的默认 snmpd.conf
文件会受到大量注释,它可作为代理配置的良好起点。
本节重点介绍两种常见任务:设置系统信息和配置身份验证。有关可用配置指令的更多信息,请参阅 snmpd.conf
(5)手册页。此外,net -snmp 软件包中也有一个名为 snmp
conf 的实用程序,可用于以交互方式生成有效的代理配置。
请注意,必须安装 net-snmp-utils 软件包,才能使用本节中描述的 snmpwalk
实用程序。
要将配置文件的任何更改生效,请以 root 用户身份
运行以下命令来强制 snmpd
服务重新读取配置:
systemctl reload snmpd.service
21.7.3.1. 设置系统信息
net-SNMP 通过系统树提供一些基本 系统
信息。例如,以下 snmpwalk
命令显示具有默认代理配置的 系统
树:
~]# snmpwalk -v2c -c public localhost system SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (464) 0:00:04.64 SNMPv2-MIB::sysContact.0 = STRING: Root <root@localhost> (configure /etc/snmp/snmp.local.conf) [output truncated]
默认情况下,sysName
对象被设置为主机名。通过更改 sys
对象,例如:
location 和 sys
Contactcontact 指令的值,可以在
/etc/snmp/snmpd.conf
文件中配置 sys Location
和 sys
syslocation Datacenter, Row 4, Rack 3 syscontact UNIX Admin <admin@example.com>
更改配置文件后,重新载入配置并再次运行 snmpwalk
命令测试它:
~]# systemctl reload snmp.service ~]# snmpwalk -v2c -c public localhost system SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (35424) 0:05:54.24 SNMPv2-MIB::sysContact.0 = STRING: UNIX Admin <admin@example.com> SNMPv2-MIB::sysName.0 = STRING: localhost.localdomain SNMPv2-MIB::sysLocation.0 = STRING: Datacenter, Row 4, Rack 3 [output truncated]
21.7.3.2. 配置身份验证
Net-SNMP 代理守护进程支持所有三种版本的 SNMP 协议。前两个版本(1 和 2c)提供使用社区字符串的简单身份验证。此字符串是代理和任何客户端实用程序之间的共享 secret。字符串通过网络以明文形式传递,但被视为不安全。SNMP 协议的版本 3 支持使用各种协议进行用户身份验证和消息加密。Net-SNMP 代理还支持通过 SSH 隧道以及 X.509 证书的 TLS 身份验证。
配置 SNMP 版本 2c 社区
要配置 SNMP 版本 2c 社区,请在 /etc/snmp/snmpd.conf
配置文件中使用 rocommunity
或 rwcommunity 指令
。指令的格式如下:
directive community source OID
… 其中社区是要使用的社区字符串 ,source 是 IP 地址或子网,OID 则是 SNMP 树,用于提供对.例如,以下指令提供了对 系统
树的只读访问,使用本地机器上的社区字符串"redhat":
rocommunity redhat 127.0.0.1 .1.3.6.1.2.1.1
要测试配置,请使用 snmpwalk
命令及 -v
和 -c
选项。
~]# snmpwalk -v2c -c redhat localhost system SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 SNMPv2-MIB::sysObjectID.0 = OID: NET-SNMP-MIB::netSnmpAgentOIDs.10 DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (101376) 0:16:53.76 SNMPv2-MIB::sysContact.0 = STRING: UNIX Admin <admin@example.com> SNMPv2-MIB::sysName.0 = STRING: localhost.localdomain SNMPv2-MIB::sysLocation.0 = STRING: Datacenter, Row 4, Rack 3 [output truncated]
配置 SNMP 版本 3 用户
要配置 SNMP 版本 3 用户,请使用 net-snmp-create-v3-user
命令。此命令向 /var/lib/net-snmp/snmpd.conf
和 /etc/snmp/snmpd.conf
文件添加条目,这些文件创建用户并为用户授予访问权限。请注意,net-snmp-create-v3-user
命令只能在代理未运行时运行。以下示例创建"admin"用户,其密码为 "redhatsnmp:
~]# systemctl stop snmpd.service ~]# net-snmp-create-v3-user Enter a SNMPv3 user name to create: admin Enter authentication pass-phrase: redhatsnmp Enter encryption pass-phrase: [press return to reuse the authentication pass-phrase] adding the following line to /var/lib/net-snmp/snmpd.conf: createUser admin MD5 "redhatsnmp" DES adding the following line to /etc/snmp/snmpd.conf: rwuser admin ~]# systemctl start snmpd.service
rwuser
指令(或者提供 -ro
命令行选项时 rouser
),net -snmp-create-v3-user
添加到 /etc/snmp/snmpd.conf
具有与 rwcommunity 和
指令类似的格式:
rocommunity
directive usernoauth
|auth
|priv
OID
… 其中 user 是用户名,OID 是 SNMP 树,用于提供对.默认情况下,Net-SNMP 代理守护进程仅允许经过身份验证的请求( auth
选项)。noauth
选项允许您允许未经身份验证的请求,而 priv
选项则强制使用加密。authpriv
选项指定请求必须经过身份验证并且应加密回复。
例如,以下行授予用户"admin"对整个树的读写访问权限:
rwuser admin authpriv .1
要测试配置,请在用户的主目录中创建一个 .snmp/
目录,并在该目录中创建一个名为 snmp.conf
的配置文件(~/.snmp/snmp.conf
):
defVersion 3 defSecurityLevel authPriv defSecurityName admin defPassphrase redhatsnmp
现在,在查询代理时,s nmpwalk
命令将使用这些身份验证设置:
~]$ snmpwalk -v3 localhost system SNMPv2-MIB::sysDescr.0 = STRING: Linux localhost.localdomain 3.10.0-123.el7.x86_64 #1 SMP Mon May 5 11:16:57 EDT 2014 x86_64 [output truncated]
21.7.4. 通过 SNMP 检索性能数据
红帽企业 Linux 中的 Net-SNMP 代理通过 SNMP 协议提供各种性能信息。此外,可以查询代理查找系统上已安装的 RPM 软件包列表、系统上当前运行的进程的列表或系统的网络配置。
本节概述 SNMP 上可用的与性能调优相关的 OID。它假定已安装 net-snmp-utils 软件包,并授予该用户 SNMP 树的访问权限,如 第 21.7.3.2 节 “配置身份验证” 所述。
21.7.4.1. 硬件配置
Net-SNMP 中包含 的主机资源 MIB
提供了有关主机当前硬件和软件配置到客户端实用程序的信息。表 21.3 “可用 OID” 总结了该 MIB 下提供的不同 OID。
OID | 描述 |
---|---|
| 包含常规系统信息,如正常运行时间、用户数和运行的进程数。 |
| 包含有关内存和文件系统使用情况的数据。 |
| 包含所有处理器、网络设备和文件系统的列表。 |
| 包含所有正在运行的进程的列表。 |
| 包含 HOST-RESOURCES-MIB::hrSWRun 进程表的内存和 CPU 统计信息。 |
| 包含 RPM 数据库的列表。 |
主机资源 MIB 中也提供了多个 SNMP 表,可用于检索可用信息的摘要。以下示例显示 HOST-RESOURCES-MIB::hrFSTable
:
~]$ snmptable -Cb localhost HOST-RESOURCES-MIB::hrFSTable
SNMP table: HOST-RESOURCES-MIB::hrFSTable
Index MountPoint RemoteMountPoint Type
Access Bootable StorageIndex LastFullBackupDate LastPartialBackupDate
1 "/" "" HOST-RESOURCES-TYPES::hrFSLinuxExt2
readWrite true 31 0-1-1,0:0:0.0 0-1-1,0:0:0.0
5 "/dev/shm" "" HOST-RESOURCES-TYPES::hrFSOther
readWrite false 35 0-1-1,0:0:0.0 0-1-1,0:0:0.0
6 "/boot" "" HOST-RESOURCES-TYPES::hrFSLinuxExt2
readWrite false 36 0-1-1,0:0:0.0 0-1-1,0:0:0.0
有关 HOST-RESOURCES-MIB
的更多信息,请参阅 /usr/share/snmp/mibs/HOST-RESOURCES-MIB.txt
文件。
21.7.4.2. CPU 和内存信息
大多数系统性能数据在 UCD SNMP MIB
中可用。systemStats
OID 围绕处理器使用情况提供多个计数器:
~]$ snmpwalk localhost UCD-SNMP-MIB::systemStats
UCD-SNMP-MIB::ssIndex.0 = INTEGER: 1
UCD-SNMP-MIB::ssErrorName.0 = STRING: systemStats
UCD-SNMP-MIB::ssSwapIn.0 = INTEGER: 0 kB
UCD-SNMP-MIB::ssSwapOut.0 = INTEGER: 0 kB
UCD-SNMP-MIB::ssIOSent.0 = INTEGER: 0 blocks/s
UCD-SNMP-MIB::ssIOReceive.0 = INTEGER: 0 blocks/s
UCD-SNMP-MIB::ssSysInterrupts.0 = INTEGER: 29 interrupts/s
UCD-SNMP-MIB::ssSysContext.0 = INTEGER: 18 switches/s
UCD-SNMP-MIB::ssCpuUser.0 = INTEGER: 0
UCD-SNMP-MIB::ssCpuSystem.0 = INTEGER: 0
UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 99
UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 2278
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 1395
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 6826
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 3383736
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 7629
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 434
UCD-SNMP-MIB::ssIORawSent.0 = Counter32: 266770
UCD-SNMP-MIB::ssIORawReceived.0 = Counter32: 427302
UCD-SNMP-MIB::ssRawInterrupts.0 = Counter32: 743442
UCD-SNMP-MIB::ssRawContexts.0 = Counter32: 718557
UCD-SNMP-MIB::ssCpuRawSoftIRQ.0 = Counter32: 128
UCD-SNMP-MIB::ssRawSwapIn.0 = Counter32: 0
UCD-SNMP-MIB::ssRawSwapOut.0 = Counter32: 0
特别是,ssCpuRawUser
、ssCpuRawSystem
、ssCpuRawWait
和 ssCpuRawIdle
OID 提供计数器,它们有助于确定系统是否在内核空间、用户空间或 I/O 中消耗大部分处理器时间。ssRawSwapIn
和 ssRawSwapOut
在确定系统是否存在内存耗尽时非常有用。
UCD-SNMP-MIB::memory
OID 下提供了更多内存信息,它提供与 可用
命令类似的数据:
~]$ snmpwalk localhost UCD-SNMP-MIB::memory
UCD-SNMP-MIB::memIndex.0 = INTEGER: 0
UCD-SNMP-MIB::memErrorName.0 = STRING: swap
UCD-SNMP-MIB::memTotalSwap.0 = INTEGER: 1023992 kB
UCD-SNMP-MIB::memAvailSwap.0 = INTEGER: 1023992 kB
UCD-SNMP-MIB::memTotalReal.0 = INTEGER: 1021588 kB
UCD-SNMP-MIB::memAvailReal.0 = INTEGER: 634260 kB
UCD-SNMP-MIB::memTotalFree.0 = INTEGER: 1658252 kB
UCD-SNMP-MIB::memMinimumSwap.0 = INTEGER: 16000 kB
UCD-SNMP-MIB::memBuffer.0 = INTEGER: 30760 kB
UCD-SNMP-MIB::memCached.0 = INTEGER: 216200 kB
UCD-SNMP-MIB::memSwapError.0 = INTEGER: noError(0)
UCD-SNMP-MIB::memSwapErrorMsg.0 = STRING:
UCD SNMP MIB 中
也提供负载平均值。SNMP 表 UCD-SNMP-MIB::laTable
包含 1、5 和 15 分钟负载平均值列表:
~]$ snmptable localhost UCD-SNMP-MIB::laTable
SNMP table: UCD-SNMP-MIB::laTable
laIndex laNames laLoad laConfig laLoadInt laLoadFloat laErrorFlag laErrMessage
1 Load-1 0.00 12.00 0 0.000000 noError
2 Load-5 0.00 12.00 0 0.000000 noError
3 Load-15 0.00 12.00 0 0.000000 noError
21.7.4.3. 文件系统和磁盘信息
主机资源 MIB
提供有关文件系统大小和使用情况的信息。每个文件系统(以及每个内存池)在 HOST-RESOURCES-MIB::hrStorageTable
表中都有一个条目:
~]$ snmptable -Cb localhost HOST-RESOURCES-MIB::hrStorageTable
SNMP table: HOST-RESOURCES-MIB::hrStorageTable
Index Type Descr
AllocationUnits Size Used AllocationFailures
1 HOST-RESOURCES-TYPES::hrStorageRam Physical memory
1024 Bytes 1021588 388064 ?
3 HOST-RESOURCES-TYPES::hrStorageVirtualMemory Virtual memory
1024 Bytes 2045580 388064 ?
6 HOST-RESOURCES-TYPES::hrStorageOther Memory buffers
1024 Bytes 1021588 31048 ?
7 HOST-RESOURCES-TYPES::hrStorageOther Cached memory
1024 Bytes 216604 216604 ?
10 HOST-RESOURCES-TYPES::hrStorageVirtualMemory Swap space
1024 Bytes 1023992 0 ?
31 HOST-RESOURCES-TYPES::hrStorageFixedDisk /
4096 Bytes 2277614 250391 ?
35 HOST-RESOURCES-TYPES::hrStorageFixedDisk /dev/shm
4096 Bytes 127698 0 ?
36 HOST-RESOURCES-TYPES::hrStorageFixedDisk /boot
1024 Bytes 198337 26694 ?
HOST-RESOURCES-MIB::hrStorageSize
和 HOST-RESOURCES-MIB::hrStorageUsed
下的 OID 可以用来计算每个挂载的文件系统的剩余容量。
UCD-SNMP-MIB::systemStats(ss
IORawSent.0 和
)和 ssIORawRecieved.0
UCD-DISKIO-MIB::diskIOTable
中都可以使用 I/O 数据。后者提供了更精细的数据。在此表中是 diskIONReadX
和 diskIONWrittenX
的 OID,它们为系统引导后读取并写入块设备的字节数提供计数器:
~]$ snmptable -Cb localhost UCD-DISKIO-MIB::diskIOTable
SNMP table: UCD-DISKIO-MIB::diskIOTable
Index Device NRead NWritten Reads Writes LA1 LA5 LA15 NReadX NWrittenX
...
25 sda 216886272 139109376 16409 4894 ? ? ? 216886272 139109376
26 sda1 2455552 5120 613 2 ? ? ? 2455552 5120
27 sda2 1486848 0 332 0 ? ? ? 1486848 0
28 sda3 212321280 139104256 15312 4871 ? ? ? 212321280 139104256
21.7.4.4. 网络信息
Interfaces MIB
提供有关网络设备的信息。IF-MIB::ifTable
提供 SNMP 表,其中包含系统上每个接口的条目、接口的配置以及接口的各种数据包计数器。以下示例显示了在有两个物理网络接口的系统中 ifTable
的前几列:
~]$ snmptable -Cb localhost IF-MIB::ifTable
SNMP table: IF-MIB::ifTable
Index Descr Type Mtu Speed PhysAddress AdminStatus
1 lo softwareLoopback 16436 10000000 up
2 eth0 ethernetCsmacd 1500 0 52:54:0:c7:69:58 up
3 eth1 ethernetCsmacd 1500 0 52:54:0:a7:a3:24 down
网络流量位于 OIDs IF-MIB::ifOutOctets
和 IF-MIB::ifInOctets
下。以下 SNMP 查询将检索此系统中每个接口的网络流量:
~]$snmpwalk localhost IF-MIB::ifDescr
IF-MIB::ifDescr.1 = STRING: lo IF-MIB::ifDescr.2 = STRING: eth0 IF-MIB::ifDescr.3 = STRING: eth1 ~]$snmpwalk localhost IF-MIB::ifOutOctets
IF-MIB::ifOutOctets.1 = Counter32: 10060699 IF-MIB::ifOutOctets.2 = Counter32: 650 IF-MIB::ifOutOctets.3 = Counter32: 0 ~]$snmpwalk localhost IF-MIB::ifInOctets
IF-MIB::ifInOctets.1 = Counter32: 10060699 IF-MIB::ifInOctets.2 = Counter32: 78650 IF-MIB::ifInOctets.3 = Counter32: 0
21.7.5. 扩展 Net-SNMP
可以扩展 Net-SNMP 代理,以提供除原始系统指标外的应用指标。这可实现容量规划以及性能问题故障排除。例如,了解电子邮件系统的负载平均值为 15 分钟,而测试期间的负载平均值为 15,但知道电子邮件系统的负载平均值为 15 次,处理第 15 条消息会很有帮助。当应用程序指标通过与系统指标相同的接口获得时,也可以视觉化了解不同负载场景对系统性能的影响(例如,每条额外的 10,000 个消息都会线性增大负载平均值到 100,000)。
红帽企业 Linux 中包含的许多应用程序扩展了 Net-SNMP 代理,以通过 SNMP 提供应用指标。另外,也可以为自定义应用程序扩展代理。本节论述了使用 shell 脚本和可选频道中的 Perl 插件扩展代理。它假设安装了 net-snmp-utils 和 net-snmp-perl 软件包,并授予该用户对 SNMP 树的访问权限,如 第 21.7.3.2 节 “配置身份验证” 所述。
21.7.5.1. 使用 Shell 脚本扩展 Net-SNMP
Net-SNMP 代理提供一个扩展 MIB(NET-SNMP-EXTEND-MIB
),可用于查询任意 shell 脚本。要指定要运行的 shell 脚本,请使用 /etc/snmp/snmpd.conf
文件中的 extend
指令。定义后,代理将通过 SNMP 提供 命令的退出代码和任何输出。以下示例通过脚本演示此机制,此脚本决定了进程表中的 httpd
进程数。
Net-SNMP 代理还提供内置机制,用于通过 proc
指令检查流程表。如需更多信息,请参阅 snmpd.conf(5)手册页。
以下 shell 脚本的退出代码是在给定时间点运行在系统上运行的 httpd
进程数:
#!/bin/sh
NUMPIDS=pgrep httpd | wc -l
exit $NUMPIDS
要使该脚本可通过 SNMP 使用,请将 脚本复制到系统路径上的位置,设置可执行位,并将 扩展
指令添加到 /etc/snmp/snmpd.conf
文件。扩展
指令的格式如下:
extend
name prog args
… 其中 name 是扩展的标识字符串,prog 是要运行的程序,args 则是提供程序的参数。例如,如果将上述 shell 脚本复制到 /usr/local/bin/check_apache.sh
中,以下指令会将脚本添加到 SNMP 树中:
extend httpd_pids /bin/sh /usr/local/bin/check_apache.sh
然后,可以在 NET-SNMP-EXTEND-MIB::nsExtendObjects 中
查询该脚本:
~]$ snmpwalk localhost NET-SNMP-EXTEND-MIB::nsExtendObjects NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 1 NET-SNMP-EXTEND-MIB::nsExtendCommand."httpd_pids" = STRING: /bin/sh NET-SNMP-EXTEND-MIB::nsExtendArgs."httpd_pids" = STRING: /usr/local/bin/check_apache.sh NET-SNMP-EXTEND-MIB::nsExtendInput."httpd_pids" = STRING: NET-SNMP-EXTEND-MIB::nsExtendCacheTime."httpd_pids" = INTEGER: 5 NET-SNMP-EXTEND-MIB::nsExtendExecType."httpd_pids" = INTEGER: exec(1) NET-SNMP-EXTEND-MIB::nsExtendRunType."httpd_pids" = INTEGER: run-on-read(1) NET-SNMP-EXTEND-MIB::nsExtendStorage."httpd_pids" = INTEGER: permanent(4) NET-SNMP-EXTEND-MIB::nsExtendStatus."httpd_pids" = INTEGER: active(1) NET-SNMP-EXTEND-MIB::nsExtendOutput1Line."httpd_pids" = STRING: NET-SNMP-EXTEND-MIB::nsExtendOutputFull."httpd_pids" = STRING: NET-SNMP-EXTEND-MIB::nsExtendOutNumLines."httpd_pids" = INTEGER: 1 NET-SNMP-EXTEND-MIB::nsExtendResult."httpd_pids" = INTEGER: 8 NET-SNMP-EXTEND-MIB::nsExtendOutLine."httpd_pids".1 = STRING:
请注意,退出代码(本示例中为"8")作为 INTEGER 类型提供,任何输出都以 STRING 类型提供。若要以整数形式公开多个指标,请使用 extend 指令向
脚本提供不同的参数。例如,以下 shell 脚本可用于确定匹配任意字符串的进程数量,同时还会输出一个文本字符串,给出的进程数量:
#!/bin/sh
PATTERN=$1
NUMPIDS=pgrep $PATTERN | wc -l
echo "There are $NUMPIDS $PATTERN processes."
exit $NUMPIDS
当以上脚本复制到 /
PID 的数量:
usr/local/bin/proc.sh 时,以下 /etc/
s nmpd.conf
指令将同时提供 httpd
PID 的数量以及 snmpd
extend httpd_pids /bin/sh /usr/local/bin/check_proc.sh httpd extend snmpd_pids /bin/sh /usr/local/bin/check_proc.sh snmpd
以下示例显示了 then sExtendObjects
OID 的 snmpwalk
的输出结果:
~]$ snmpwalk localhost NET-SNMP-EXTEND-MIB::nsExtendObjects NET-SNMP-EXTEND-MIB::nsExtendNumEntries.0 = INTEGER: 2 NET-SNMP-EXTEND-MIB::nsExtendCommand."httpd_pids" = STRING: /bin/sh NET-SNMP-EXTEND-MIB::nsExtendCommand."snmpd_pids" = STRING: /bin/sh NET-SNMP-EXTEND-MIB::nsExtendArgs."httpd_pids" = STRING: /usr/local/bin/check_proc.sh httpd NET-SNMP-EXTEND-MIB::nsExtendArgs."snmpd_pids" = STRING: /usr/local/bin/check_proc.sh snmpd NET-SNMP-EXTEND-MIB::nsExtendInput."httpd_pids" = STRING: NET-SNMP-EXTEND-MIB::nsExtendInput."snmpd_pids" = STRING: ... NET-SNMP-EXTEND-MIB::nsExtendResult."httpd_pids" = INTEGER: 8 NET-SNMP-EXTEND-MIB::nsExtendResult."snmpd_pids" = INTEGER: 1 NET-SNMP-EXTEND-MIB::nsExtendOutLine."httpd_pids".1 = STRING: There are 8 httpd processes. NET-SNMP-EXTEND-MIB::nsExtendOutLine."snmpd_pids".1 = STRING: There are 1 snmpd processes.
整数退出代码限制为 0-255 范围。对于可能超过 256 的值,请使用脚本的标准输出(将键入为字符串)或不同的扩展代理方法。
最后一个示例显示了对系统的可用内存和 httpd
进程数量的查询。此查询可用于性能测试,以确定进程数量对内存压力的影响:
~]$ snmpget localhost \ 'NET-SNMP-EXTEND-MIB::nsExtendResult."httpd_pids"' \ UCD-SNMP-MIB::memAvailReal.0 NET-SNMP-EXTEND-MIB::nsExtendResult."httpd_pids" = INTEGER: 8 UCD-SNMP-MIB::memAvailReal.0 = INTEGER: 799664 kB
21.7.5.2. 使用 Perl 扩展 Net-SNMP
使用 extend
指令执行 shell 脚本是一种相当受限的方法,用于通过 SNMP 公开自定义应用指标。Net-SNMP 代理还提供嵌入式 Perl 接口来公开自定义对象。Optional 频道中的 net-snmp-perl 软件包提供 NetSNMP::agent
Perl 模块,用于在 Red Hat Enterprise Linux 中编写嵌入式 Perl 插件。
在订阅 Optional 和 Supplementary 频道前,请查看覆盖范围详情。如果您决定从这些频道安装软件包,请按照红帽客户门户网站中名为 How to access Optional 和 Supplementary 频道以及 -devel 软件包(RHSM)中的步骤进行操作。
NetSNMP::agent
Perl 模块提供了一个 代理
对象,用于处理代理 OID 树的一部分的请求。agent
对象的构造器具有作为 snmpd
或独立代理的子代理运行代理的选项。创建嵌入式代理不需要任何参数:
use NetSNMP::agent (':all'); my $agent = new NetSNMP::agent();
代理
对象具有一个 寄存器
方法,用于使用特定的 OID 注册回调函数。register
函数将名称 OID 和指针用于回调函数。以下示例将使用 SNMP Agent 注册名为 hello_handler
的回调函数,该代理将处理 OID .1.3.6.1.4.1.8072.9999.9999
下的请求:
$agent->register("hello_world", ".1.3.6.1.4.1.8072.9999.9999", \&hello_handler);
OID .1.3.6.1.4.1.8072.9999.9999
(NET-SNMP-MIB::netSnmpPlaypen
)通常仅用于演示目的。如果您的组织还没有根 OID,可以通过联系美国 ISO 名称注册机构(ANSI)来获取一个。
该处理程序功能将通过四个参数调用: HANDLER
、REGISTRATION_INFO
、REQUEST_INFO
和 REQUESTS
。REQUESTS
参数包含当前调用中的请求列表,应迭代并使用数据填充。列表中 的请求
对象具有 get 和 set 方法,允许操作请求的 OID
和 值
。例如,以下调用会将请求对象的值设置为字符串 "hello world":
$request->setValue(ASN_OCTET_STR, "hello world");
处理程序函数应响应两种类型的 SNMP 请求:GET 请求和 GETNEXT 请求。请求类型通过调用作为第三个参数传递给处理程序函数的 request_info
对象的 getMode
方法来确定。如果请求是 GET 请求,调用者将预期处理程序设置 请求
对象 的值
,具体取决于请求的 OID。如果请求是 GETNEXT 请求,调用者还将请求的 OID 设置为树中下一个可用的 OID。下面的代码示例演示了这种情况:
my $request; my $string_value = "hello world"; my $integer_value = "8675309"; for($request = $requests; $request; $request = $request->next()) { my $oid = $request->getOID(); if ($request_info->getMode() == MODE_GET) { if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setValue(ASN_OCTET_STR, $string_value); } elsif ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.1")) { $request->setValue(ASN_INTEGER, $integer_value); } } elsif ($request_info->getMode() == MODE_GETNEXT) { if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.1"); $request->setValue(ASN_INTEGER, $integer_value); } elsif ($oid < new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.0"); $request->setValue(ASN_OCTET_STR, $string_value); } } }
当 getMode
返回 MODE_GET
时,处理程序会分析 请求
对象上 getOID
调用的值。如果 OID 以 ".1.0" 结束,请求
的值
将设为 string_value
,如果 OID 以 ".1.1" 结束,则设置为 integer_value
。如果 getMode
返回 MODE_GETNEXT
,处理程序将决定请求的 OID 是否为 ".1.0",然后设置 OID 和值 ".1.1"。如果树上的请求高于 ".1.0",则设置了 ".1.0" 的 OID 和值。实际上,这将返回树中的"下一步"值,以便 snmpwalk
等程序可以遍历树,而不必事先了解结构。
变量的类型使用 NetSNMP::ASN 中的
常量来设置。有关可用常数的完整列表,请参阅 NetSNMP::ASN
的 perldoc
。
这个示例 Perl 插件的完整代码列表如下:
#!/usr/bin/perl use NetSNMP::agent (':all'); use NetSNMP::ASN qw(ASN_OCTET_STR ASN_INTEGER); sub hello_handler { my ($handler, $registration_info, $request_info, $requests) = @_; my $request; my $string_value = "hello world"; my $integer_value = "8675309"; for($request = $requests; $request; $request = $request->next()) { my $oid = $request->getOID(); if ($request_info->getMode() == MODE_GET) { if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setValue(ASN_OCTET_STR, $string_value); } elsif ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.1")) { $request->setValue(ASN_INTEGER, $integer_value); } } elsif ($request_info->getMode() == MODE_GETNEXT) { if ($oid == new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.1"); $request->setValue(ASN_INTEGER, $integer_value); } elsif ($oid < new NetSNMP::OID(".1.3.6.1.4.1.8072.9999.9999.1.0")) { $request->setOID(".1.3.6.1.4.1.8072.9999.9999.1.0"); $request->setValue(ASN_OCTET_STR, $string_value); } } } } my $agent = new NetSNMP::agent(); $agent->register("hello_world", ".1.3.6.1.4.1.8072.9999.9999", \&hello_handler);
要测试插件,请将上述程序复制到 /usr/share/snmp/hello_world.pl
,并将以下行添加到 /etc/snmp/snmpd.conf
配置文件:
perl do "/usr/share/snmp/hello_world.pl"
需要重启 SNMP 代理守护进程来加载新的 Perl 插件。重启后,s nmpwalk
应该返回新数据:
~]$ snmpwalk localhost NET-SNMP-MIB::netSnmpPlaypen
NET-SNMP-MIB::netSnmpPlaypen.1.0 = STRING: "hello world"
NET-SNMP-MIB::netSnmpPlaypen.1.1 = INTEGER: 8675309
snmpget
也应用于操作处理程序的其他模式:
~]$snmpget localhost \
NET-SNMP-MIB::netSnmpPlaypen.1.0 \
NET-SNMP-MIB::netSnmpPlaypen.1.1
NET-SNMP-MIB::netSnmpPlaypen.1.0 = STRING: "hello world" NET-SNMP-MIB::netSnmpPlaypen.1.1 = INTEGER: 8675309