DatadogのSNMP Integrationを利用してネットワーク機器を監視する

<img width="1129" alt="スクリーンショット 2018-03-11 23.13.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/375/760c9c9b-1fa5-7cb5-fe60-a6cc25371a88.png">
# はじめに
ネットワーク機器の監視を行う場合 `snmp` を利用し監視を行うのが一般的です。
今回はDatadogのSNMP Integrationを利用し監視を行う事が出来るか検証をしました。監視対象の機器はCitrix NetScaler MPXを対象として、OIDやMIBを指定して取得する方法から、拡張MIBファイルをSNMP Integration用の `ysnmp` 形式に変換し監視を行うまでを実践してみたいと思います。
##環境
・監視ホスト `CentOS: 6.9 Python: 2.7.14`
・監視対象 `Citrix NetScaler MPX 11515 NS 11.0 71.22.nc`

# 手順
監視ホストにインストールした `Datadog Agent` でSNMP Checkを利用するため `/etc/dd-agent/conf.d` ディレクトリ内にある `snmp.yaml.example` をリネームし `snmp.yaml` を作成します。
##機器への接続情報を設定する
```yaml
instances:
   - ip_address: 10.10.10.10
     port: 161
     community_string: citrix
     snmp_version: 2
     timeout: 1
     retries: 5
     enforce_mib_constraints: true
```
ここでは監視対象の `IP ` `port` `community名` `snmpバージョン` を指定します。
##OIDでの取得
```yaml
     metrics:
       - OID: 1.3.6.1.4.1.5951.4.1.1.41.6.1.2
         name: nsCPUusage

       - OID: 1.3.6.1.4.1.5951.4.1.1.41.2
         name: resMemUsage
```
機器のOIDをsnmpwalkや[Citrixの公式リファレンス](https://developer-docs.citrix.com/projects/netscaler-snmp-oid-reference/en/11.0/)を参考に取得したいOIDとDatadog上でのメトリクス名を指定します。
##MIBとSymbolを指定
```yaml
     metrics:
     - MIB: IF-MIB
      symbol: ifInOctets
```
直接シンボルを指定し取得する事も可能です。

##動作確認
snmp.conf を設定後 `service datadog-agent restart` エージェントのリスタートを行い `service datadog-agent info` コマンドで正しく値が取得できていることを確認します。

```bash

    snmp (1.3.1)
    ------------
      - instance #0 [OK]
      - Collected 274 metrics, 0 events & 1 service check
```
このように`Collected metrics` と正しくメトリクス数が表示されて取得が開始されている事が確認できます。
もし取得が上手く出来ていない場合は `/var/log/datadog/collector.log` からエラー内容を確認してください。

<img width="849" alt="スクリーンショット 2018-03-11 20.38.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/375/7ea895cc-1738-1d47-2662-b02fe57b1a97.png">

ダッシュボードから取得した値を表示し上手く取得が出来ている事を確認できました。

# ベンダー固有の拡張MIBファイルの設定

ここまでは簡単に取得する事が可能でしたが、ベンダー固有の拡張MIBを取得したい場合、Zabbix等ではMIBファイルをサイトからDLしてきて配置するだけで利用可能ですが、Datadogの場合そのまま配置する事が出来ないので `ysnmp` 形式に変換したファイルを用意する必要があります。Datadogの公式リファレンスに情報が少なくいくつか試行錯誤が必要が必要でした。

## 変換の用意
変換するにあたり、`pysnmp`に包容されている `build-pysnmp-mib` コマンドを実行する環境の用意が必要になります。 [SNMP library for Python](http://pysnmp.sourceforge.net/contents.html) または [Package Index pysnmp](https://pypi.python.org/pypi/pysnmp) 等から準備してください。

## MIBファイルを入手
<img width="734" alt="スクリーンショット 2018-03-11 21.13.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/375/37c63119-2816-53d4-7f6e-df11fe034157.png">
NetScalerの場合は、機器にGUIからログインしDownload > SNMP Files に用意されています。
今回は`SNMP v2 - MIB Object Definitions`を利用します。
各ベンダーによって取得方法が異なるので、 [Junos OS Enterprise MIBs](https://www.juniper.net/documentation/en_US/release-independent/junos/mibs/mibs.html) や [Cisco MIB tools](https://mibs.cloudapps.cisco.com/ITDIT/MIBS/servlet/index) などから対象機器のファイルを取得してください。
## MIBファイルを変換
用意したMIBファイルを`build-pysnmp-mib`コマンドを利用し `ysnmp` 形式に変換します。

```bash:build-pysnmp-mib
build-pysnmp-mib -o 変換後ファイル名.py 変換したいMIBファイル名.mib
```
変換が完了するとpython形式のファイルが作成されました。

## 変換後のPythonファイルの読み込み
変換したPythonファイルを `/etc/dd-agent/mibs`というディレクトリを作成し配置します。

```yaml
init_config:
     mibs_folder: /etc/dd-agent/mibs
```
Datadogから作成したディレクトリを読み込むために snmp.yaml内の `init_config` に先程作成したディレクトリを追記します。

## 拡張MIBの指定
```yaml
       - MIB: NS-ROOT-MIB
         table: vlanEntry
         symbols:
           - vlanTotRxBytes
           - vlanTotTxBytes
         metric_tags:
           - tag: vlan
             column: vlanAliasName
```
今回はCitrixの拡張MIBで取得できる、Vlan毎の受信と送信量を監視するため `vlanTotRxBytes` `vlanTotTxBytes`を指定しました。カラムには `vlanAliasName`を指定して各Vlan毎のエイリアス名と紐付けるようにしています。
## 動作確認

追記後 `service datadog-agent restart` エージェントのリスタートを行ったところ以下のエラーが発生しました。

```bash

      - instance #0 [WARNING]
          Warning: Fail to collect some metrics: MIB module "/etc/dd-agent/mibs/NS-ROOT-MIB.py" load error: ['Traceback (most recent call last):\n', '  File "/opt/datadog-agent/embedded/lib/python2.7/site-packages/pysnmp/smi/builder.py", line 331, in loadModule\n    exec (modData, g)\n', '  File "<string>", line 1005, in <module>\n', "NameError: name 'Counter64' is not defined\n"]
          Warning: Fail to collect some metrics: MIB module "/etc/dd-agent/mibs/NS-ROOT-MIB.py" load error: ['Traceback (most recent call last):\n', '  File "/opt/datadog-agent/embedded/lib/python2.7/site-packages/pysnmp/smi/builder.py", line 331, in loadModule\n    exec (modData, g)\n', '  File "<string>", line 1005, in <module>\n', "NameError: name 'Counter64' is not defined\n"]
      - Collected 0 metrics, 0 events & 1 service check
```

変換後のPythonファイルでシンタックス `Counter64` が何故か定義されていなかったようです。

```py


( Bits, Counter32, Counter64, Gauge32, Integer32, Integer32, IpAddress, ModuleIdentity, MibIdentifier, NotificationType, ObjectIdentity, MibScalar, MibTable, MibTableRow, MibTableColumn, TimeTicks, TimeTicks, enterprises, ) = mibBuilder.importSymbols("SNMPv2-SMI", "Bits", "Counter32", "Counter64", "Gauge32", "Integer32", "Integer32", "IpAddress", "ModuleIdentity", "MibIdentifier", "NotificationType", "ObjectIdentity", "MibScalar", "MibTable", "MibTableRow", "MibTableColumn", "TimeTicks", "TimeTicks", "enterprises")
```
あらためてシンタックスを定義したところ正しく読み込む事ができました。

![a.png](https://qiita-image-store.s3.amazonaws.com/0/375/74ff817e-1149-f3cd-e185-c3596bc5aaa0.png)

実際にダッシュボードから取得した値を表示しToplistとグラフを利用し、Vlan毎の送信・受信量の監視とVlan毎のグラフを表示する事が出来ました。値の中には指定したVlanと紐付いているエイリアス名が表示されているので、どのサービスが多く通信を行っているのか一見して確認することが出来ます。

# まとめ
今回はDatadog SNMP Integrationを利用してオンプレミス環境にある Citrix NetScalerの監視を行いましたが、監視を行うまでのハードルは高いものの、Datadogはネットワーク機器の監視にもかなり使えそうです。また今後は Datadog logs を利用したsyslogの監視も検証してみたいと思います。

# 参考
https://docs.datadoghq.com/integrations/snmp