研究室でL2スイッチを2台,L3スイッチを1台使っています.
どれもSNMPに対応しているので,Sensuを使って監視してみました.
監視スクリプト
Rubyのgem 'snmp'
を使ってスクリプトを書きました.
対象スイッチ(IPアドレスをカンマ区切り)とSNMPコミュニティを指定して使います.
スイッチを複数指定可能にしたのは,Sensuの設定を簡素にするためです.
スイッチごとにスレッドを作って,マルチスレッドで処理します.
MIB1.3.6.1.2.1.2.2.1.10
以下に各ポートの起動後の累計通信量があります.
今回はそれらを合計して,秒間の通信総量を取得するようにしました.
snmp-traffic-metrics.rb
# !/usr/bin/env ruby
require 'sensu-plugin/metric/cli'
require 'snmp'
class SNMPTrafficMetrics < Sensu::Plugin::Metric::CLI::Graphite
option :hosts,
short: '-h HOSTS',
long: '--hosts HOSTS',
default: 'localhost,127.0.0.1'
option :community,
short: '-c COMMUNITY',
long: '--community COMMUNITY',
default: 'public'
option :sleep,
long: '--sleep SLEEP',
proc: proc {|a| a.to_f },
default: 1
def get_all_traffic(host, community)
manager = SNMP::Manager.new host: host, community: community
i = 1
traffic = 0
loop do
response = manager.get ["1.3.6.1.2.1.2.2.1.10.#{i}"]
begin
response.each_varbind { |vb| traffic += vb.value.to_i }
rescue NoMethodError
break
end
i += 1
end
traffic
end
def run
timestamp = Time.now.to_i
threads = []
config[:hosts].split(',').each do |host|
threads << Thread.new do
net_traffic_before = get_all_traffic(host, config[:community])
sleep config[:sleep]
net_traffic_after = get_all_traffic(host, config[:community])
all_traffic = net_traffic_after - net_traffic_before
output "#{host}.snmp.all.traffic", all_traffic, timestamp
end
end
threads.each do |thread|
thread.join
end
ok
end
end
sensu-serverの設定
スイッチ上でsensu-clientは動かせないので,別のホスト上から監視します.
上で書いた通り,カンマで区切って複数スイッチを監視することができます.
スクリプトはsubscription"snmp"
のホスト上で実行されます.
ここでは,結果のMetricsをElasticsearchに投げています.
/etc/sensu/conf.d/metrics_snmp.json
{
"checks": {
"snmp-traffic-metrics": {
"type": "metric",
"handlers": [ "elasticsearch_metrics" ],
"command": "/etc/sensu/plugins/snmp-traffic-metrics.rb -h 192.168.1.1,192.168.11.254",
"interval": 60,
"subscribers": [ "snmp" ]
}
}
}
Kibanaで可視化
Elasticsearch + Kibanaで可視化してみました.
実験すると大きな通信があるので,すぐ分かりますね.