Collectd的SNMP模塊搭配Logstash

前言

最近使用 ELK/G 在彙整資料, 雖然說 Logstash 已經能幫我們處理 netflow, log, api 等資訊, 但還有一樣東西是運維不可或缺的: 沒錯就是snmp !!

秉持 hello world 的精神, 這篇先介紹怎麼使用 collectd snmp 模塊抓取本機的資訊, 熟悉之後就可以把資料拋給 logstash 囉

安裝環境: Ubuntu 16.04 LTS


安裝和配置 snmp 及 collectd

apt-get install snmp snmpd collectd
mv /etc/snmp/snmpd.conf /etc/snmp/snmpd.conf.bak
echo "rwcommunity mysnmp" >> /etc/snmp/snmpd.conf

這樣就安裝和配置完成snmpd部份了哦, 可以看到剛才把預設的配置檔做備份, 真正的配置目前只有rwcommunity mysnmp 這樣一行而已哦! 這是個人習慣, 一來可以很清楚自己下的設定, 二來未來再次部屬的時候也可以很快的copy paste哦!

改完設定檔以後記得要重新啟動服務systemctl restart snmpd


配置Collectd

Collectd 基礎配置

cat /etc/collectd.conf                                                          
Hostname    "localhost"
LoadPlugin logfile
LoadPlugin write_log
LoadPlugin snmp
TypesDB    "/usr/share/collectd/types.db"
TypesDB    "/usr/share/collectd/types.db.custom"

<Plugin logfile>
        LogLevel info
        File STDOUT
        Timestamp true
        PrintSeverity false
</Plugin>
<Plugin snmp>
  <Data "std_traffic">
      Type "if_octets"
      Table true
      Instance "IF-MIB::ifDescr"
      Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
  </Data>
  <Host "my_archlinux">
      Address "127.0.0.1"
      Version 1
      Community "pp"
      Collect "std_traffic"
      Interval 10
  </Host>
</Plugin>

名詞解釋:
Hostname: 讓別人知道是誰在採資料
logfile: 寫入檔案的模塊, 必須和write_log一起使用, STDOUT 就是在畫面打印啦
write_log: 寫入採集到的 metric, 等到測試完成這個可以註解掉哦~
snmp: 就是採集snmp的模塊囉
<Data "std_traffic">:採集資料名, 自取, 稍後會在Host用到
Instance "IF-MIB::ifDescr": 資料參照名, 這邊就是網卡的敘述名稱
Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets" 實際要採集的資料
<Host "my_archlinux">: 主機名, 自取辨識用
Collect "std_traffic":剛才取的採集資料名

這時候執行sudo collectd -f 就可以看到資料打印囉

[2017-08-18 00:56:52] plugin_load: plugin "logfile" successfully loaded.       
[2017-08-18 00:56:52] plugin_load: plugin "snmp" successfully loaded.          
[2017-08-18 00:56:52] plugin_load: plugin "write_log" successfully loaded.     
[2017-08-18 00:56:52] Initialization complete, entering read-loop.             
[2017-08-18 00:56:52] write_log values:                                        
my_archlinux.snmp.if_octets-lo.rx 6065342 1502989012                           
my_archlinux.snmp.if_octets-lo.tx 6065342 1502989012                           

[2017-08-18 00:56:52] write_log values:                                        
my_archlinux.snmp.if_octets-tun0.rx 548103 1502989012                          
my_archlinux.snmp.if_octets-tun0.tx 471309 1502989012                          

[2017-08-18 00:56:52] write_log values:                                        
my_archlinux.snmp.if_octets-Intel_Corporation_Wireless_3160.rx 327940 1502989012                                                                               
my_archlinux.snmp.if_octets-Intel_Corporation_Wireless_3160.tx 248255 1502989012                                                                               

[2017-08-18 00:56:52] write_log values:                                        
my_archlinux.snmp.if_octets-Qualcomm_Atheros_Killer_E220x_Gigabit_Ethernet_Controller.rx 1208338895 1502989012                                                 
my_archlinux.snmp.if_octets-Qualcomm_Atheros_Killer_E220x_Gigabit_Ethernet_Controller.tx 64125573 1502989012                                                   

^C[2017-08-18 00:56:53] Exiting normally.                                      
[2017-08-18 00:56:53] collectd: Stopping 5 read threads.                       
[2017-08-18 00:56:53] collectd: Stopping 5 write threads.       

上面 Collect 抓到的資訊分別是
Host - Type - Type-Instance - Metric - Timestamp

OK! 沒問題了, 那我們就進行下一步吧!



來配置和Logstash的傳接球吧

Collect 配置

cat /etc/collectd/collectd.conf
LoadPlugin logfile
<Plugin logfile>
	LogLevel info
	File STDOUT
	Timestamp true
	PrintSeverity false
</Plugin>
LoadPlugin network
LoadPlugin snmp
LoadPlugin write_log
<Plugin network>
    <Server "192.168.40.43" "25826">
    </Server>
</Plugin>
<Plugin snmp>
  <Data "std_traffic">
      Type "if_octets"
      Table true
      Instance "IF-MIB::ifDescr"
      Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
  </Data>
  <Host "my_archlinux">
      Address "127.0.0.1"
      Version 1
      Community "pp"
      Collect "std_traffic"
      Interval 10
  </Host>
</Plugin>

可以看到這邊就是多了一個 network模塊, 要填入 logstash 的 ip 哦, 25826 就是我設定 logstash 監聽(接球)的埠號/端口


Logstash 配置

不熟悉的人先看這篇

input {
  udp {
    port => 25826
    buffer_size => 1452
    codec => collectd { }
    type => "collectd"
  }
}

filter {}

output {
if [type] == "collectd" {
  stdout {                   
    codec => rubydebug       
  }  
  elasticsearch {
    hosts => ["192.168.40.44:9200"]
    index => "collectd-%{+YYYY.MM.dd}"
        }
  }
}

這邊的 Collectd 和 Logstash 都有開啟 stdout (標準輸出) , 先確定配置沒有問題; 之後用 daemon 模式開啟就不需要囉

確定資料沒問題之後, 就可以用 systemctl start collectd 的方式來執行囉!


常見問題集

模塊表示: 我只接受x個值, 你卻給我y個
[2018-03-18 05:16:25] snmp plugin: DataSet `memory' requires 1 values, but config talks about 2

這是在說什麼呢?
原來是type造成的. 什麼意思? 有看到上面設定檔有個types.db嗎, 設定檔裡面的type就是去參照他的, 我們看一下types.db裡面他提到的memory部份.

tommy@ubuntu:~/collectd$ grep memory /usr/share/collectd/types.db
memory                  value:GAUGE:0:281474976710656
memory_lua              value:GAUGE:0:281474976710656
vs_memory              value:GAUGE:0:9223372036854775807

當你今天使用memory這個type的時候, 就不能回傳多個值, 這時候你可以建立一個自己的, 記得要再設定檔裡面把這個types.db.custom也加進去

tommy@ubuntu:~/collectd$ grep memory /usr/share/collectd/types.db.custom
linux_memory                    mem_total:GAUGE:0:281474976710656 mem_avail:GAUGE:0:281474976710656

然後type就可以選擇linux_memory這樣就好嚕


我想導入其他的MIB, 要怎麼做呢?

要導入其他廠商的MIB可以參考這個
導入mib


我的syslog裡面出現很多UDP connection ftom xxx這樣的垃圾訊息

可以用下面的配置來指定日誌等級

# RHEL OS
cat /etc/sysconfig/snmp
# OPTIONS="-LS0-6d"
# Ubuntu OS
cat /etc/default/snmpd
SNMPDOPTS='-LS4d -Lf /dev/null -u snmp -g snmp -I -smux,mteTrigger,mteTriggerConf -p /run/snmpd.pid'

可以參考這裡


我的syslog裡面有這些訊息 snmpd[1234] Cannot statfs /run/user/1000/gvfs: Permission denied

snmp 官方說這個無法防止, 所以請在rsyslog端做忽略

cat /etc/rsyslog.d/040-snmp-statfs.conf

if $programname == 'snmpd' and $msg contains 'statfs' then {
   stop
}

還有哪些OID可以用?

喂~這不算問題吧?
linux 常用