前回、SDカードをマウントして、そこそこ信頼性のある大容量(!?)ストレージを確保した、 GL-iNet GL-AR750S OpenWRT ルータに vnstat を入れて、永続的なトラフィック監視を実現します。
導入とLUCIでの使い方
vnstat の導入自体はとても簡単、以下のパッケージを opkg で入れるだけです。
- vnstat
- luci-app-vnstat
インストール後、サービス開始させることで記録が始まり、LuCI上でグラフを閲覧できます。
記録したいインターフェースは隣りの設定タブで選択します。
データベース保存先の変更
但し、 vnstat のデータベースはこのままでは、 /var/lib/vnstat/ という tmpfs の領域に配置されているので、機器を再起動してしまうとこれまでのデータは消え去り、またまっさらなデータベースから記録が始まってしまいます。
そこで、OpenWRT公式サイトに挙げられている、Persistent stats (1) に沿って、データベースのパスをSDカード上に変更します。まず、 vnstat サービスを停止させ、
1 |
# service vnstat stop |
SDカード上にフォルダを作成し、既存のデータベースをそこへ移してから、設定ファイルを編集します。
1 2 3 |
# location of the database directory #DatabaseDir "/var/lib/vnstat" #Default Location DatabaseDir "/mnt/sda1/vnstat/db" #New Location |
サービスを再開させ、
1 |
# service vnstat start |
念の為、元の場所にもうデータベースが生成されていないことを確認。以上で再起動しても失われないデータベースになりました。
レポートメール送信
次にレポートメール送信の仕組みです。これは既にRaspberry Piで使っているPythonスクリプトを流用します。 vnstati でグラフ画像を生成、それをメールに貼り付け送信というとてもシンプルなものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
import sys, os, smtplib, shutil from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.Utils import formatdate from email import Encoders def send_mail(send_from, send_to, subject, body, path_att): cset = 'utf-8' msg = MIMEMultipart() msg['From'] = send_from msg['To'] = send_to msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject if body != '': msg.attach( MIMEText(body, 'plain', cset) ) files = os.listdir(path_att) files.sort() i = 1 for f in files: part = MIMEBase('application', "octet-stream") part.set_payload( open(path_att + f,"rb").read() ) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(path_att + f)) part.add_header('Content-ID', '<image' + str(i) + '>') msg.attach(part) body = body + '<img src="cid:image' + str(i) + '"><br />' i += 1 msg.attach( MIMEText(body, 'html', cset) ) ## SMTP TO GMAIL smtp = smtplib.SMTP('smtp.gmail.com', 587) smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login('test@example.com', '##PASSWORD##') smtp.sendmail(send_from, send_to, msg.as_string()) smtp.quit() if __name__ == '__main__': ifs = [filename for filename in os.listdir('/mnt/sda1/vnstat/db/') if not filename.startswith('.')] path = '/mnt/sda1/vnstat/repo/' shutil.rmtree(path, ignore_errors=True) if not os.path.exists(path): os.makedirs(path) for n in ifs: os.system('vnstati -d -i ' + n + ' -o ' + path + n + '_daily.png') os.system('vnstati -vs -i ' + n + ' -o ' + path + n + '_hsum.png') subj = os.uname()[1] + ': Daily Traffic Report' txt = '' send_mail('##FROM_ADDR##', '##TO_ADDR##', subj, txt, path) |
上記はGmailの587番ポートを例にしていますが、ロリポップなど465番を指定してくるところでは、以下の要領へ変更するだけです。
1 2 3 4 5 6 |
## SMTP TO MAIL 465 smtp = smtplib.SMTP_SSL('smtp.lolipop.jp', 465, timeout=10) smtp.ehlo() smtp.login('test@example.com', '##PASSWORD##') smtp.sendmail(send_from, send_to, msg.as_string()) smtp.quit() |
このスクリプトを cron へ登録しておけば毎日、次のようなメールで使用状況を確認することが出来ます。
まずはWAN、LANを監視対象にしていますが、負荷を見ながらWiFiなどにも対象拡大してみるつもりです。
参考
追記
メール送信スクリプトを動かすに必要なPythonパッケージを確かめようと最小限でこれらをいれるも、
- python-base
- python-email
- python-openssl
結局、 encodings はどこやねんと怒られ、素直に以下を入れました。
- python