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


telegraf + influxdb + grafana で YAMAHA RTX830 を可視化する (telegraf編 1) に引き続き、まだ可視化できていなかった

NAT セッション

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

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

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

参考: プロバイダを変更してネット人権を一夜で回復した話

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

参考: NATディスクリプターを監視する

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

1. syslog 転送

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

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

2. http ソケット

そこでこれです。"rt.httprequest"。lua スクリプト内から HTTPリクエストを送出できます。ええやん。

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

telegraf.conf の設定

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

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

lua スクリプトの準備

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

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 でどうぞ