telegraf + influxdb + grafana で YAMAHA RTX830 を可視化する (telegraf編 2)

[telegraf + influxdb + grafana で YAMAHA RTX830 を可視化する (telegraf編 1)](https://qiita.com/sho7650/items/b824acf3c9345937ff05) に引き続き、まだ可視化できていなかった

**NAT セッション**

をなんとか取得していきます。取得できるとこんな感じになります。

![Screen Shot 2021-02-11 at 20.32.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/2c2567c1-a1cb-3c97-1dc3-3eefa8cbfb8a.png)

## YAMAHA RTシリーズの NATセッション

もうすでに、わが家では NATセッション(ポート)数などといったものにとらわれた生活は送っていません。それでも、NATセッション数がとれないことや、実際にどれくらいの通信が発生しているのだろうかの**指針**としてのNATセッション数はわりかし有能です。

参考: [プロバイダを変更してネット人権を一夜で回復した話](https://note.com/sho7650/n/n540ce8eef2e7)

しかしながら、YAMAHA RTシリーズでは NATのセッション数をとりたいとなると`luaスクリプト`での実装一択です。

参考: [NATディスクリプターを監視する](https://network.yamaha.com/setting/router_firewall/monitor/lua_script/nat)

snmp で取得できないなら仕方ない、他の方法をとるしかないと様々な方法を考えました。

### 1. syslog 転送

YAMAHA RTシリーズでは、syslog 転送機能がありますので、これを利用して telegraf+influxdb の稼働しているサーバに送りつける方法が一つ考えられます。

が、しかし。YAMAHA RTシリーズにログを大量に吐くような真似はあまりしたくありません。できれば、記録は telegraf+influxdb だけにとどまるようにしたい。

### 2. http ソケット

そこでこれです。"[rt.httprequest](http://www.rtpro.yamaha.co.jp/RT/docs/lua/rt_api.html#rt_httpreq)"。lua スクリプト内から HTTPリクエストを送出できます。ええやん。

ということで、telegraf 側に http受信する場所を準備して、lua スクリプトから送りつける方法を採択しました。

## telegraf.conf の設定

設定は簡単これだけです。これで、`8186`ポートで待ち受けます。influx に特化した Lisnter が使いやすいので、`influxdb_listerner`を使います。後継が出てるようですが、こっちのがさっぱりしてたので、これで行きます。

```config:telegraf.conf
[[inputs.influxdb_listener]]
  ## Address and port to host HTTP listener on
  service_address = ":8186"

  ## maximum duration before timing out read of the request
  read_timeout = "10s"
  ## maximum duration before timing out write of the response
  write_timeout = "10s"

  ## Maximum allowed HTTP request body size in bytes.
  ## 0 means to use the default of 32MiB.
  max_body_size = 0
```

これだけです。

参考: [influxDB Listener Input Plugin](https://github.com/influxdata/telegraf/blob/master/plugins/inputs/influxdb_listener/README.md)

## lua スクリプトの準備

実際に書いたスクリプトはこちらです。冒頭の変数定義部分を自宅用に修正して、登録すれば利用できます。気をつけるべきは文字コードです。tftp/scp で送信するときには "`shift-jis`" であることをお忘れなきよう。

```lua:nat_logging.lua
idle_time = 30 -- nat session 取得サイクル(秒数)
nat_descriptor = 20000 -- nat descriptor の番号
log_level = "info"
measure = "rtx830" -- telegraf の measurement
request_url = "http://<ホスト名>:<ポート番号>/write"
check_if = "lan1" -- agent_host となるインタフェイス

-- インタフェイスのIPアドレスを取得
function get_local_ip(interface)
  local rtn, str, ipadr
  local cmd = "show status " .. interface
  local ptn = "IPアドレス:%s+(%d+%.%d+%.%d+%.%d+)"

  rtn, str = rt.command(cmd)

  if (rtn) and (str) then
    ipadr = str:match(ptn)

    if (ipadr == nil) then
      rtn   = false
      str = interface .. " not linked up\r\n"
    end
  else
    str = cmd .. ": command executes failure\r\n"
  end

  return rtn, ipadr, str
end

-- NAT セッション数の取得
function natmsq_use_status(id)
  local rtn, str, num
  local cmd = "show nat descriptor address " .. tostring(id)
  local ptn = "(%d+) セッション"

  rtn, str = rt.command(cmd)
  if (rtn) and (str) then
    num = str:match(ptn)
    if (num) then
    num = tonumber(num)
    end
  else
    str = cmd .. ": command executes failure\r\n"
  end
  return rtn, num, str
end

local rtn, nat_use, ipadr, str

-- メインループ
while (true) do
  rtn, ipadr, str = get_local_ip(check_if)

  if (rtn) and (ipadr) then
    rtn, nat_use, str = natmsq_use_status(nat_descriptor)

    if (rtn) and (nat_use) then
      req_table = {
        url = request_url,
        method = "POST",
        content_type = "application/x-www-form-urlencoded",
        post_text = string.format("%s,agent_host=%s nat=%d", measure, ipadr, nat_use)
      }
      rt.httprequest(req_table)
      end
  end

  rt.sleep(idle_time)
end
```

あとはふつーに `lua /nat_logging.lua` しておけば終わりです。 `rt.syslog` 入れてないのはエラーログすら吐いてほしくないからです。ほしい人は適切に `str` を出力するように入れ込んであげてください。

※ emfs上に配置してたら `lua emfs:/nat_logging.lua` でどうぞ