--[[ ●ルーターリソース監視スクリプト   一定の監視間隔毎にルーターの状態を監視し、設定した閾値を超えたら管理者に   メールを送信して知らせるスクリプトです。   監視する情報は以下の通りです。   ・CPU 使用率   ・メモリ使用率   ・筐体内温度(RTX1200 のみ)   ・PP 側回線使用率(送信/受信)   ・IP マスカレード使用ポート数   各リソースの値が閾値を指定した回数だけ連続して超えた場合に、管理者にメール   を送信します。その後、値が閾値を指定した回数だけ連続して下回った場合には、   正常値に戻ったと判断します。設定値 down_mail を true に設定している場合には、   正常値に戻った際にもメールを送信します。 <説明> ・このファイルを RTFS か外部メモリに保存してください。 ・本項目の config の設定では schedule at コマンドでルーター起動時に Lua スク  リプトが実行されるように設定しています。 ・スクリプトを停止するときは terminate lua コマンドを実行してください。 ・再度、Lua スクリプトを実行する場合は lua コマンドで実行してください。 ・★マークの付いた設定値は変更が可能です。 <ノート>  ・メールの送信失敗時に出力する SYSLOG レベルを指定可能です。   SYSLOG のレベルを指定するには、log_level を設定してください。   debug レベル、notice レベルの SYSLOG を出力するためには、それぞれ以下の設定   が必要です。    debug レベル ・・・ syslog debug on    notice レベル・・・ syslog notice on  ・本スクリプトファイルを編集する場合、文字コードは必ず Shift-JIS を使用してく   ださい。 ]] --------------------------## 設定値 ##-------------------------------- -- 監視間隔(1 - 864000 秒) idle_time = (監視間隔) -- ★ -- CPU 負荷率を監視する単位時間("5sec" or "1min" or "5min") cpu_time = "(単位時間)" -- ★ -- 監視する相手先情報番号(1 - 30) peer_num = (相手先情報番号) -- ★ -- 使用状況を監視するIP マスカレードの NAT ディスクリプタ番号(1 - 2147483647) nat_descriptor = (NAT ディスクリプタ番号)-- ★ -- 各リソースの閾値(1 - 99) th_tbl = { -- ★ cpu = (CPU 使用率(%)), mem = (メモリ使用率(%)), tmp = (筐体内温度(℃)), -- RTX1200 のみ snd = (PP インタフェース送信負荷率(%)), rcv = (PP インタフェース受信負荷率(%)), nat = (IP マスカレード 使用ポート数(個)) } -- 連続で閾値を超えたら異常と判断する回数、または正常な状態に復帰したと判断する回数(1, 2 ..) count = (回数) -- ★ -- 正常な状態に復帰した場合にもメールを送るか否か(送る: true / 送らない: false) down_mail = (true / false) -- ★ -- メールの設定 mail_tbl = { -- ★ smtp_address = "(SMTP サーバのアドレス)", from = "(送信元メールアドレス)", to = "(宛先メールアドレス)" } -- メールの送信に失敗した時に出力する SYSLOG のレベル (info, debug, notice) log_level = "(SYSLOG レベル)" -- ★ ----------------------## 設定値ここまで ##---------------------------- ------------------------------------------------------------ -- 指定した単位時間のCPU使用率を取得するための検索文字列 -- -- を設定する関数 -- ------------------------------------------------------------ function set_cpu_ptn(key) local ptn if (key == "5sec") or (key == "1min") or (key == "5min") then ptn = "(%d+)%%%(" .. key .. "%)" return ptn end return nil end ------------------------------------------------------------ -- ルーターのハードウェアリソースの使用状況を取得する関数 -- ------------------------------------------------------------ function rt_res_status(t) local rtn, str local cmd = "show environment" rtn, str = rt.command(cmd) if (rtn) and (str) then for k, v in pairs(t) do v.val = str:match(v.ptn) if (v.val) then v.val = tonumber(v.val) end end else str = cmd .. "コマンド実行失敗\r\n\r\n" end return rtn, str end ------------------------------------------------------------ -- PP インタフェースの回線負荷率を求める関数 -- ------------------------------------------------------------ function pp_load_info(num) local rtn, snd, rcv, str, n local t = {} local cmd = "show status pp " .. tostring(num) local ptn = "負荷%:%s+(%d+)%.%d+%%" rtn, str = rt.command(cmd) if (rtn) and (str) then n = 1 for w in string.gmatch(str, ptn) do t[n] = w n = n + 1 end if (t[1]) then rcv = tonumber(t[1]) end if (t[2]) then snd = tonumber(t[2]) end end return rtn, rcv, snd, str end ------------------------------------------------------------ -- IP マスカレード使用ポート数を返す関数 -- ------------------------------------------------------------ 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 .. "コマンド実行失敗\r\n" end return rtn, num, str end ------------------------------------------------------------ -- 各状態の数値が閾値を超えた時、または正常に復帰した時に -- -- メッセージを返す関数 -- ------------------------------------------------------------ function make_msg(t, val, th, down) local rtn local str = "" if (val) then rtn = count_proc(t, val, th) if (rtn < 0) then if (down) then str = t.title .. "が閾値以下の値に下がりました。" end elseif (rtn > 0) then str = t.title .. "が閾値を超えました。\r\n" str = str .. string.format(" %s: %d%s\r\n 閾値: %d%s\r\n\r\n", t.title, val, t.unit, th, t.unit) end end return str end ------------------------------------------------------------ -- 閾値を超えた、または下回った連続回数をカウントする関数 -- ------------------------------------------------------------ function count_proc(t, val, th) local rtn = 0 if (val > th) then if (not t.flag) then t.over = t.over + 1 if (t.over == count) then rtn = 1 t.flag = true end else if (t.down > 0) then t.down = 0 end end else if (t.flag) then t.down = t.down + 1 if (t.down == count) then rtn = -1 t.flag = false t.over = 0 t.down = 0 end else if (t.over > 0) then t.over = 0 end end end return rtn end ------------------------------------------------------------ -- 現在の日時を取得する関数 -- ------------------------------------------------------------ function time_stamp() local t t = os.date("*t") return string.format("%d/%02d/%02d %02d:%02d:%02d", t.year, t.month, t.day, t.hour, t.min, t.sec) end ------------------------------------------------------------ -- メインルーチン -- ------------------------------------------------------------ -- ハードウェアリソース情報テーブル local res_tbl = { cpu = {ptn = "", val = 0, over = 0, down = 0, flag = false, title = "CPU負荷率(" .. cpu_time .. ")", unit = "%"}, mem = {ptn = "(%d+)%% used", val = 0, over = 0, down = 0, flag = false, title = "メモリ使用率", unit = "%%"}, tmp = {ptn = "筐体内温度%(℃%): (%d+)", val = 0, over = 0, down = 0, flag = false, title = "筐体内温度", unit = "℃"} } local pp_tbl = { rcv = {over = 0, down = 0, flag = false, title = "PP 受信負荷率", unit = "%"}, snd = {over = 0, down = 0, flag = false, title = "PP 送信負荷率", unit = "%"} } local nat_tbl = {over = 0, down = 0, flag = false, title = "NAT マスカレードテーブル 使用ポート数", unit = "個"} local rtn, str, nat_use local rt_name = string.match(_RT_FIRM_REVISION, "(%w+)") res_tbl.cpu.ptn = set_cpu_ptn(cpu_time) assert(res_tbl.cpu.ptn) while (true) do mail_tbl.text = "" -- cpu, mem (,temp -- RTX1200 only) rtn, str = rt_res_status(res_tbl) if (rtn) then mail_tbl.text = mail_tbl.text .. make_msg(res_tbl.cpu, res_tbl.cpu.val, th_tbl.cpu, down_mail) mail_tbl.text = mail_tbl.text .. make_msg(res_tbl.mem, res_tbl.mem.val, th_tbl.mem, down_mail) if (rt_name == "RTX1200") then mail_tbl.text = mail_tbl.text .. make_msg(res_tbl.tmp, res_tbl.tmp.val, th_tbl.tmp, down_mail) end end -- pp rtn, rcv, snd, str = pp_load_info(peer_num) if (rtn) then mail_tbl.text = mail_tbl.text .. make_msg(pp_tbl.rcv, rcv, th_tbl.rcv, down_mail) mail_tbl.text = mail_tbl.text .. make_msg(pp_tbl.snd, snd, th_tbl.snd, down_mail) else mail_tbl.text = str end -- nat rtn, nat_use, str = natmsq_use_status(nat_descriptor) if (rtn) then if (nat_use) then mail_tbl.text = mail_tbl.text .. make_msg(nat_tbl, nat_use, th_tbl.nat, down_mail) end else mail_tbl.text = str end if (mail_tbl.text:len() > 0) then mail_tbl.subject = string.format("resource loadwatch (%s)", time_stamp()) rtn = rt.mail(mail_tbl) if (not rtn) then rt.syslog(log_level, "failed to send mail. (Lua スクリプトファイル名)") end end rt.sleep(idle_time) end