CollectdとSNMPによるLANのLink Up/Down検知をCloudWatchに通知する

以前、SNMPトラップを使って、LANのLink Up/DownをCloudWatchに通知しました。
　[SNMPトラップによる LANのLink Up/Down検知 をCloudWatchに通知する](https://qiita.com/poruruba/items/06743cbf7373dad3e52a)

今回は、もっと汎用的な手段で行いたく、普段動かしているCollectdの機能を使って実現してみます。

以下の投稿を参考にさせていただきました。

* [ネットワークメトリクスを視覚化してみた（collectd + Graphite + Grafana）](https://qiita.com/kooshin/items/cbab9dd3fc7b1f4eed81)
* [新しい collectd の CloudWatch プラグイン](https://aws.amazon.com/jp/blogs/news/new-cloudwatch-plugin-for-collectd/)

また、ついでに、Collectdで保存された履歴をGraphiteに出力するようにして、Apache2またはGrafana経由でブラウザから参照できるようにします。

# 手順

ちなみに、Apache2とSNMPサーバがインストールされている前提です。
SNMPについては以下を参考にして下さい。
　[SNMPトラップによる LANのLink Up/Down検知 をCloudWatchに通知する](https://qiita.com/poruruba/items/06743cbf7373dad3e52a)

・Graphiteのインストール
　これで、collectdで出力される履歴を保持できるようになります。
・collectdのインストール
　これで、自身のPCの稼働情報や、他のPCの稼働情報を取得できるようになります。
・CollectdのためのCloudWatchプラグインのセットアップ
　これで、Collectdで取得される情報をCloudWatchにも転送できるようになります。

# Graphiteのインストール

以下をインストールします。

```
> apt-get install graphite-carbon graphite-web graphite-web apache2 libapache2-mod-wsgi
```

途中以下のように聞かれますが、Noでいいでしょう。

<pre>
lqqqqqqqqqqqqqqqqqqqu graphite-carbon を設定しています tqqqqqqqqqqqqqqqqqqqqk
 x                                                                           x
 x /var/lib/graphite/whisper ディレクトリに whisper のデータベースファイル   x
 x があります。                                                              x
 x                                                                           x
 x graphite-carbon を完全に削除する場合でも、後で再インストールする予定であ  x
 x ればデータベースファイルは残しておくのがいいかもしれません。              x
 x                                                                           x
 x graphite-carbon の完全削除でデータベースファイルを削除しますか?           x
 x                                                                           x
 x                    <はい>                      <いいえ>                   x
 x                                                                           x
 mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
</pre>

以下のファイルを編集します。
　/etc/default/graphite-carbon

```
CARBON_CACHE_ENABLED=false
→
CARBON_CACHE_ENABLED=true
```

さらに、以下のファイルを編集します。
　/etc/carbon/carbon.conf


```
ENABLE_LOGROTATION = False
→
ENABLE_LOGROTATION = True
```

以下のファイルに追記します。
　/etc/carbon/storage-schemas.conf
[carbon]と[default_1min_for_1day]の間に挿入します。

```
[collectd]
pattern = ^collectd\.
retentions = 30:90d,300:365d
```

以下で再起動して変更した内容を反映します。
　systemctl restart carbon-cache
　systemctl status carbon-cache

以下のファイルを編集します。
　/etc/graphite/local_settings.py

```
#SECRET_KEY = 'UNSAFE_DEFAULT'
→
SECRET_KEY = '適当な値'

#TIME_ZONE = 'America/Los_Angeles'
→
TIME_ZONE = 'Asia/Tokyo'
```

次に、以下で、Webアプリのデータベースを同期するそうです。

```
> sudo -u _graphite -g _graphite graphite-manage migrate –run-syncdb
```

次からの作業は、Graphiteに保存した情報を、Apache2から参照できるようにします。

```
> cp /usr/share/graphite-web/apache2-graphite.conf /etc/apache2/sites-available/
```

コピーした apache2-graphite.confに対して変更します。

```
<VirtualHost *:80>
→
<VirtualHost *:8080>
```

デフォルトで80ポートでApache2が立ち上がっているため、別のポートでバーチャルホストを立ち上げます。
以下も忘れずに編集します。

/etc/apache2/port.conf

以下を追記します。

```
Listen 8080
```

最後に、VirtualHostを有効にします。

```
> a2ensite apache2-graphite
```

さっそく、以下のようにポート8080をブラウザからアクセスしてみましょう。
　http://localhost:8080

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/f24dd778-a1e3-98ee-b0fc-c90eee5f5b0c.png)

まだ収集していないので、何も表示されていません。

# Collectdのインストール

以下をインストールします。

```
> apt-get install collectd
```

次に、SNMPもcollectdで取得するために、以下を編集します。
　/etc/collectd/collectd.conf

```
#LoadPlugin snmp
→
LoadPlugin snmp

#LoadPlugin write_graphite
→
LoadPlugin write_graphite


#<Plugin write_graphite>
#        <Node "example">
#                Host "localhost"
#                Port "2003"
#                Protocol "tcp"
#                ReconnectInterval 0
#                LogSendErrors true
#                Prefix "collectd."
#                Postfix "collectd"
#                StoreRates true
#                AlwaysAppendDS false
#                EscapeCharacter "_"
#                SeparateInstances false
#                PreserveSeparator false
#                DropDuplicateFields false
#        </Node>
#</Plugin>
→
<Plugin write_graphite>
        <Node "example">
                Host "localhost"
                Port "2003"
                Protocol "tcp"
                ReconnectInterval 0
                LogSendErrors true
                Prefix "collectd."
#               Postfix "collectd"
                StoreRates true
                AlwaysAppendDS false
                EscapeCharacter "_"
                SeparateInstances false
                PreserveSeparator false
                DropDuplicateFields false
        </Node>
</Plugin>
```

さらに、以下の、Plugin snmpの部分を編集します。

```
<Plugin snmp>
#       <Data "powerplus_voltge_input">
#               Type "voltage"
#               Table false
#               Instance "input_line1"
#               Scale 0.1
#               Values "SNMPv2-SMI::enterprises.6050.5.4.1.1.2.1"
#       </Data>
#       <Data "hr_users">
#               Type "users"
#               Table false
#               Instance ""
#               Shift -1
#               Values "HOST-RESOURCES-MIB::hrSystemNumUsers.0"
#       </Data>
#       <Data "std_traffic">
#               Type "if_octets"
#               Table true
#               InstancePrefix "traffic"
#               Instance "IF-MIB::ifDescr"
#               Values "IF-MIB::ifInOctets" "IF-MIB::ifOutOctets"
#       </Data>
        <Data "lan_link_remote">
                Type "if_status"
                Table true
                InstancePrefix "link_remote-"
                Values "IF-MIB::ifAdminStatus"
        </Data>


        <Host "【Link監視対象のホスト名】">
                Address "【Link監視対象のホスト名】"
                Version 2
                Community "public"
                Collect "lan_link_remote"
                Interval 60
        </Host>

#       <Host "some.switch.mydomain.org">
#               Address "192.168.0.2"
#               Version 1
#               Community "community_string"
#               Collect "std_traffic"
#               Inverval 120
#       </Host>
#       <Host "some.server.mydomain.org">
#               Address "192.168.0.42"
#               Version 2
#               Community "another_string"
#               Collect "std_traffic" "hr_users"
#       </Host>
#       <Host "some.ups.mydomain.org">
#               Address "192.168.0.3"
#               Version 1
#               Community "more_communities"
#               Collect "powerplus_voltge_input"
#               Interval 300
#       </Host>
</Plugin>
```

（参考情報）
　https://collectd.org/documentation/manpages/collectd-snmp.5.shtml

IF-MIB::ifAdminStatus が、SNMPのLAN Link Up/Downの状態になります。1がUp、2がDown、3がTestだそうです。

Type "if_status" は、IF-MIB::ifAdminStatus  で取得される値の型を示しています。
型の指定は以下のファイルです。
　/usr/share/collectd/type.db

以下の行を適当な場所に追加します。

```
if_status               value:GAUGE:1:3
```

1:3としているのは、有効な値の範囲が1～3であるためです。
GAUGEやDERIVE、COUNTERなどは、以下を実行すると表示されるヘルプが参考になります。

```
> man rrdcreate
```

collectdを再起動しましょう
　systemctl restart collectd
　systemctl status collectd

もし途中で設定を間違って、Graphiteにゴミがたまっているようでしたら、以下に履歴が保存されていますので、削除してください。
　/var/lib/graphite/whisper


ちょっと待ってから、以下のURLをブラウザで開いてみます。
　http://localhost:8080

Metric→collectd→【Link監視対象のホスト名】→snmp というのができているかと思います。（絵では、別のSNMP取得データも取り込んでいます）
例えば、「if_status-link_remote-1」を選択すると、1または2となっているかと思います。これがLinkのUp/Down状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/fbf64329-e873-d4bd-f3b2-01706b058d41.png)

# CollectdのためのCloudWatchプラグインのセットアップ

以下のように、Gitからクローンします。

```
> git clone https://github.com/awslabs/collectd-cloudwatch.git
> cd collectd-cloudwatch/src
```

以下のように、setup.pyを実行します。

```
> sudo ./setup.py
Installing dependencies ... OK
Installing python dependencies ... OK
Downloading plugin ... OK
Extracting plugin ... OK
Moving to collectd plugins directory ... OK
Copying CloudWatch plugin include file ... OK

AWS region could not be automatically detected. 
Enter one of the available regions from: http://docs.aws.amazon.com/general/latest/gr/rande.html#cw_region
Enter region: ap-northeast-1

IAM Role could not be automatically detected.
Enter absolute path to AWS credentials file [/home/XXXXXXX/.aws/credentials]:

Enter proxy server name:
  1. None
  2. Custom
Enter choice [1]:

Enter proxy server port:
  1. None
  2. Custom
Enter choice [1]:

Include the Auto-Scaling Group name as a metric dimension:
  1. No
  2. Yes
Enter choice [1]:

Include the FixedDimension as a metric dimension:
  1. No
  2. Yes
Enter choice [1]:

Enable high resolution:
  1. Yes
  2. No
Enter choice [2]:

Enter flush internal:
  1. Default 60s
  2. Custom
Enter choice [1]:

Choose how to install CloudWatch plugin in collectd:
  1. Do not modify existing collectd configuration
  2. Add plugin to the existing configuration
  3. Use CloudWatch recommended configuration (4 metrics)
Enter choice [3]: 1
```

collectdへのCloudWatch pluginの適用はこれから手動で行うため、1を選択しておきます。
IAMのクレデンシャルには、CloudWatchへput-metric-dataする権利がある必要があります。

今一度、以下のファイルを編集します。
　/etc/collectd/collectd.conf

```
#LoadPlugin logfile
→
LoadPlugin logfile

<Plugin logfile>
       LogLevel info
       File "/var/log/collectd.log"
       Timestamp true
       PrintSeverity false
</Plugin>
```

（参考）
　https://github.com/awslabs/collectd-cloudwatch

また、以下ようにして、collectdの対象に含めます。

```
cd /etc/collectd/collectd.conf.d
ln -s /etc/collectd-cloudwatch.conf .
```

これで、一度collectdを再起動します。
　systemctrl restart collectd
　systemctrl status collectd

以下のディレクトリに移動します。
　/opt/collectd-plugins/cloudwatch/config

そうすると、blocked_metrics という名前のファイルに、CloudWatchにアップできるメトリクスの候補がたくさんあります。
この中から、アップしたいメトリクスを同じディレクトリにあるwhitelist.confに書き込みます。

LANのLink Up/downの場合は以下です。（LANインターフェースの数は、PCによって異なります。）

```
snmp--if_status-link_remote-2
snmp--if_status-link_remote-3
snmp--if_status-link_remote-68
snmp--if_status-link_remote-5
snmp--if_status-link_remote-1
snmp--if_status-link_remote-4
snmp--if_status-link_remote-74
```

ワイルドカードを.* で指定できるので、以下をwhitelist.confに追記します。

```
snmp--if_status-link_remote-.*
```

再度Collectdを再起動します。
　systemctrl restart collectd
　systemctrl status collectd

今度は、blocked_metricsにあったsnmp--if_status-link_remote-XX のメトリクスがなくなっているかと思います。whitelist.confに挙げられたためです。

それでは、CloudWatchを見てみましょう
collectedというメトリクス→Host,PluginInstanceの配下に、追加されているのがわかります。(ほかのメトリクスもCloudWatchにアップしているので、混在しています）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/e462ad0b-cecb-c23a-2f29-49b88372349d.png)

# おまけ：Grafanaから参照する

Graphiteに保持できていれば、Grafanaから可視化できます。

Data Sourcesの追加で、Graphiteを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/60beaed2-1ffa-a196-7d4a-1ca1fe67beff.png)

Graphiteで指定したApache2の参照URLとポート番号を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/4c91e5eb-5548-e416-6f79-72d93884153e.png)

あとは、Dashboardでこのデータソースを貼り付ければよいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261826/04bd6a25-dc69-cc67-1a99-ac0ec310dff6.png)

以上です。