使用SNMP进行监视
首先
使用SNMP进行监控是从很久以前就开始了的,
MRTG、Munin、Cacti、Zabbix等等,有很多工具可以选择。
但最近流行的开源软件监控工具很受欢迎,我想尝试一下,看看能否轻松地实现监控。
我对collectd、fluentd和prometheus进行了比较。
由于Collectd和Fluentd用于数据路由,所以假定使用Graphite、InfluxDB等作为数据存储。但是由于这些配置目前并不相关,所以没有在此处提及。
收集数据
插件可以做到。
设置可以进行调整。
LoadPlugin snmp
<Plugin snmp>
<Data "dataname">
Type "tipename"
Table true
Instance "IF-MIB::ifDescr"
Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
</Data>
<Data "dataname">
Type "users"
Table false
Instance ""
Shift -1
Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0"
</Data>
<Host "Hostname">
Address "192.168.1.1"
Version 2
Interval 60
Community "another_string"
Collect "dataname" "dataname" "dataname"
</Host>
</Plugin>
插件加载,
数据定义,如果是索引的话,要使用在 Instance 中指定的内容作为索引名称。
主机定义(指定要收集的数据)。
由于数据定义和主机定义是分开的,所以设置不会变得很复杂。
但是,无法对数据定义进行分组,所以主机的收集可能会变得非常冗长。
Fluentd 流畅日志管理工具
在插件中可以进行适配。
设置可以调整。
<source>
type snmp
tag snmp.hostname
host "192.168.1.1"
Community "another_string"
mib ifDescr, ifInOctets, ifOutOctets
method_type walk
polling_time 1
out_executor "/path/of/exec.rb"
</source>
<source>
type snmp
tag snmp.hostname
host "192.168.1.1"
Community "another_string"
mib "hrSystemNumUsers.0"
method_type get
</source>
由于要对主机名和数据进行定义设置,所以当要收集的数据和主机数量增多时,源定义会不断增加,这很麻烦。如果什么都不做,收集到的数据会以Value={Name=hoge,Value=fuga}这样的形式传送,所以可能需要准备exec.rb进行处理,否则会很麻烦。
以下是我尝试将接口加工成 ifDescr.ifInOctets=value,ifDescr.ifOutOctets=value 的输出结果。
module Fluent
class SnmpInput
def out_exec manager, opts={}
manager.walk(opts[:mib]) do |row|
time = Time.now.to_i
time = time - time % 5
record = {}
data = {}
row.each do |vb|
data["name"] = vb.value.to_s if vb.name.to_s =~ /Descr/
data["InOctets"] = vb.value.to_s if vb.name.to_s =~ /InOctets/
data["OutOctets"] = vb.value.to_s if vb.name.to_s =~ /OutOctets/
end
if data.has_key?("name")
record["#{data['name']}.InOctets"] = data["InOctets"] if data.has_key?("InOctets")
record["#{data['name']}.OutOctets"] = data["OutOctets"] if data.has_key?("OutOctets")
end
if record
router.emit opts[:tag], time, record
end
end
end
end
end
由于我们只关注值,不用担心收集数据类型是否是计数器,所以如果能进行差分计算,那么需要使用另外的fluentd筛选器或者数据存储进行处理,然后将其作为计数器值输入。
普罗米修斯
可以使用Exporter进行处理。
配置分别由snmp_exporter和Prometheus进行。
数据定义由snmp_exporter处理,轮询设置由Prometheus处理。
specialnode:
version: 2
auth:
community: "another_string"
walk:
- 1.3.6.1.2.1.2
- 1.3.6.1.2.1.25.1.5
metrics:
- name: ifInOctets
oid: 1.3.6.1.2.1.2.2.1.10
indexes:
- labelname: ifDescr
type: Integer32
lookups:
- labelname: ifDescr
oid: 1.3.6.1.2.1.2.2.1.2
- name: ifOutOctets
oid: 1.3.6.1.2.1.2.2.1.16
indexes:
- labelname: ifDescr
type: Integer32
lookups:
- labelname: ifDescr
oid: 1.3.6.1.2.1.2.2.1.2
- name: hrSystemNumUsers
oid: 1.3.6.1.2.1.25.1.5
以下是snmp_exporter的数据定义。
在这里,我们使用名为specialnode的名称进行了一个定义。
在这个状态下,运行snmp_exporter,
使用curl命令”curl “http://snmp_exporterhost:9116/snmp?targer=hostname&module=specialnode”
可以看到可以捕获到数据。
scrape_configs:
- job_name: 'snmp'
scrape_interval: 60s
target_groups:
- targets:
- 192.168.1.1
metrics_path: /snmp
params:
module: [specialnode]
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 127.0.0.1:9116
在 Prometheus 的一侧,我们将其注册为作业,并定期从 Prometheus 前往 snmp_exporter 进行数据收集。
与 fluentd 类似,Prometheus 对于计数器数据无法直接进行差分计算等操作,因此需要进行处理。
但是,由于我还没有进行过相关研究,所以不清楚这方面是否会很麻烦。
在Prometheus中进行差分计算
在Prometheus中,提供了一个名为rate的聚合函数作为差分计算方法。
根据上述配置,收集到的数据包括每60秒的ifInOctets等内容,
如果在Graph的表达式中写入rate(IfInOctets[5m]),则会显示5分钟内的差分。
此外,还可以在配置文件中添加该设置。
rule_files:
- prometheus.rule
在文件(prometheus.rule)中记录并描述收集规则。
ifInOctets_5min_rate = rate(ifInOctets[5m])
如果要记录,将以 ifInOctets_5min_rate 为名称保存5分钟的差分值。
由于计算率需要两个数据,所以如果要计算1分钟的差分值,需要进行一些调整,例如将 scrape_interval 设为30秒。
ifInbps_5min_average = rate(ifInOctets[5m])*8/300
我们也可以这样计算bps。
结尾
我已经确认了使用SNMP进行监视所需的设置差异。就设置文件的编写而言,仅使用fluentd好像不太适合这个用途,感觉有些麻烦。不管怎样,如果有人说我们会创建这样的生成器,那就无话可说了。