Node.jsでSNMPエージェントから値を取得する

Node.jsでSNMPの値を取得します。

# 利用するnpmモジュール

net-snmp を使います。

https://github.com/markabrahams/node-net-snmp

# 独自MIBファイルを追加する

標準MIBは以下が参考になります。(非常に助かってます)
　[ネットワーク機器のSNMP MIB/OIDまとめ](https://qiita.com/Mabuchin/items/d435c0afb4f0ca17ad25)

場合によって、監視対象の機器が独自の情報を提供している場合があります。
その場合、MIBファイルを提供しているのがほとんどです。

●Synology製 NASの場合
　https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_DiskStation_MIB_Guide.pdf
　https://global.download.synology.com/download/Document/Software/DeveloperGuide/Firmware/DSM/All/enu/Synology_MIB_File.zip

●QNAP製 NASの場合
QNAPのWeb管理コンソールから
1.	［コントロールパネル］ > ［ネットワークとファイルサービス］ > ［SNMP］に進みます。
2.	［SNMP MIB］の下で、［ダウンロード］をクリックします。

Node.jsを実行するPCの以下のフォルダにコピーします。

　```/usr/share/snmp/mibs```

既存のMIBファイルとの混同を避けるために、それぞれフォルダを作成して配置しました。

```
/usr/share/snmp/mibs/QNAP
/usr/share/snmp/mibs/Synology_MIB_File
```

フォルダを作成して配置した場合、そのフォルダもsnmpコマンドからの検索対象とするように設定する必要があります。
以下のファイルを編集します。

　```/etc/snmp/snmp.conf```

以下を追加します。最後の2つのフォルダがポイントです。

```
mibdirs /usr/share/snmp/mibs:/usr/share/snmp/mibs/iana:/usr/share/snmp/mibs/ietf:/usr/share/mibs/site:/usr/share/mibs/iana:/usr/share/mibs/ietf:/usr/share/mibs/netsnmp:$HOME/.snmp/mibs:/usr/share/snmp/mibs/QNAP:/usr/share/snmp/mibs/Synology_MIB_File
```

これで、参照されるようになります。
Synology_DiskStation_MIB_Guide.pdfを参照すると、OID：.1.3.6.1.4.1.6574.1 などがある模様。

```
> snmptranslate -Tp .1.3.6.1.4.1.6574.1
+--synoSystem(1)
   +-- -R-- Integer32 systemStatus(1)
   |        Range: 1..2
   +-- -R-- Integer32 temperature(2)
   +-- -R-- Integer32 powerStatus(3)
   |        Range: 1..2
   |
   +--fan(4)
   |  |
   |  +-- -R-- Integer32 systemFanStatus(1)
   |  |        Range: 1..2
   |  +-- -R-- Integer32 cpuFanStatus(2)
   |           Range: 1..2
   |
   +--dsmInfo(5)
   |  |
   |  +-- -R-- String    modelName(1)
   |  +-- -R-- String    serialNumber(2)
   |  +-- -R-- String    version(3)
   |  +-- -R-- Integer32 upgradeAvailable(4)
   |           Range: 1..5
   |
   +-- -R-- Integer32 controllerNumber(6)
   |
   +--systemConformance(7)
      |
      +--systemCompliances(1)
      |  |
      |  +--systemCompliance(1)
      |
      +--systemGroups(2)
         |
         +--systemGroup(1)
```

-Tpオプションは、配下をツリー表示するオプションです。

# 取得する対象OIDを選択する

MIBファイルから、取得したい情報を探しましょう。
温度関係を取得したかったので、temperatureでGrep検索しました。

MIBファイルのうち以下のあたりが大事です。

```
SYNOLOGY-SYSTEM-MIB DEFINITIONS ::= BEGIN

・・・

temperature OBJECT-TYPE
    SYNTAX	  Integer32
    MAX-ACCESS  read-only
    STATUS	  current
    DESCRIPTION
    "Synology system temperature
	 The temperature of Disk Station uses Celsius degree.
	"
    ::= { synoSystem 2 }
```

2つの単語をくっつけます。

　```SYNOLOGY-SYSTEM-MIB::temperature```

そして、以下のいずれかのコマンドを使います。
前者は先ほどの名前からOIDを取得し、後者はOIDから名前を取得します。

```
> snmptranslate -On 名前
> snmptranslate OID
```

実行例です。

```
> snmptranslate -On SYNOLOGY-SYSTEM-MIB::temperature
.1.3.6.1.4.1.6574.1.2

> snmptranslate .1.3.6.1.4.1.6574.1.2
SYNOLOGY-SYSTEM-MIB::temperature
```

それは、実際に対象機器から値を取得してみます。

```
> snmpwalk -v 1 -c public [SNMPエージェントのホスト名] SYNOLOGY-SYSTEM-MIB::temperature -On
.1.3.6.1.4.1.6574.1.2.0 = INTEGER: 56
```

OIDは「.1.3.6.1.4.1.6574.1.2.0」で取得でき、その値は「56」であることがわかりました。
さっそく、Node.jsプログラムから取得してみます。

```js
const snmp = require ("net-snmp");

function getSnmpByOid(host, oids){
  var session = snmp.createSession(host, "public");

  return new Promise((resolve, reject) =>{
    session.get (oids, function (error, varbinds) {
      if (error){
        session.close();
        return reject(error);
      }
      session.close();

      var result = {};
      for( let item of varbinds )
          result[item.oid] = item.value
      resolve(result);
    });
  })
}

var result = await getSnmpByOids("【SNMPエージェントのホスト名】", [".1.3.6.1.4.1.6574.2.1.1.6.0", "1.3.6.1.4.1.6574.1.2.0"]);
console.log(result);
```

以下が出力です。

```
{ '.1.3.6.1.4.1.6574.2.1.1.6.0': 45, '1.3.6.1.4.1.6574.1.2.0': 58 }
```

以上