diff options
author | Jo-Philipp Wich <jo@mein.io> | 2017-07-28 15:57:44 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2017-07-28 16:26:42 +0200 |
commit | 0fe93fc3a3c9402a5d0af4415ed140df20f14953 (patch) | |
tree | 0ee17eefdec9efc455ccb896f171f1bc73cc3a25 /applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua | |
parent | ee6110b3ac9433484045b61604a86f9917d8f279 (diff) |
luci-app-nlbwmon: new package
This commit introduces luci-app-nlbwmon, a frontend for nlbwmon, the
lightweight NetLink BandWidth Montor.
The nlbwmon daemon gathers per-host traffic statistics by querying netlink
accounting data. Due to this approach, the executable is very small and does
not rely on libpcap and CPU intensive raw sockets to monitor traffic.
Depends on PR https://github.com/openwrt/packages/pull/4646
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua')
-rw-r--r-- | applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua b/applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua new file mode 100644 index 0000000000..4f41bb8c31 --- /dev/null +++ b/applications/luci-app-nlbwmon/luasrc/controller/nlbw.lua @@ -0,0 +1,216 @@ +-- Copyright 2017 Jo-Philipp Wich <jo@mein.io> +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.nlbw", package.seeall) + +function index() + entry({"admin", "nlbw"}, firstchild(), _("Bandwidth Monitor"), 80) + entry({"admin", "nlbw", "display"}, template("nlbw/display"), _("Display"), 1) + entry({"admin", "nlbw", "config"}, cbi("nlbw/config"), _("Configuration"), 2) + entry({"admin", "nlbw", "backup"}, template("nlbw/backup"), _("Backup"), 3) + entry({"admin", "nlbw", "data"}, call("action_data"), nil, 4) + entry({"admin", "nlbw", "list"}, call("action_list"), nil, 5) + entry({"admin", "nlbw", "ptr"}, call("action_ptr"), nil, 6).leaf = true + entry({"admin", "nlbw", "download"}, call("action_download"), nil, 7) + entry({"admin", "nlbw", "restore"}, post("action_restore"), nil, 8) +end + +local function exec(cmd, args, writer) + local os = require "os" + local nixio = require "nixio" + + local fdi, fdo = nixio.pipe() + local pid = nixio.fork() + + if pid > 0 then + fdo:close() + + while true do + local buffer = fdi:read(2048) + local wpid, stat, code = nixio.waitpid(pid, "nohang") + + if writer and buffer and #buffer > 0 then + writer(buffer) + end + + if wpid and stat == "exited" then + break + end + end + elseif pid == 0 then + nixio.dup(fdo, nixio.stdout) + fdi:close() + fdo:close() + nixio.exece(cmd, args, nil) + nixio.stdout:close() + os.exit(1) + end +end + +function action_data() + local http = require "luci.http" + + local types = { + csv = "text/csv", + json = "application/json" + } + + local args = { } + local mtype = http.formvalue("type") or "json" + local delim = http.formvalue("delim") or ";" + local period = http.formvalue("period") + local group_by = http.formvalue("group_by") + local order_by = http.formvalue("order_by") + + if types[mtype] then + args[#args+1] = "-c" + args[#args+1] = mtype + else + http.status(400, "Unsupported type") + return + end + + if delim and #delim > 0 then + args[#args+1] = "-s%s" % delim + end + + if period and #period > 0 then + args[#args+1] = "-t" + args[#args+1] = period + end + + if group_by and #group_by > 0 then + args[#args+1] = "-g" + args[#args+1] = group_by + end + + if order_by and #order_by > 0 then + args[#args+1] = "-o" + args[#args+1] = order_by + end + + http.prepare_content(types[mtype]) + exec("/usr/sbin/nlbw", args, http.write) +end + +function action_list() + local http = require "luci.http" + + local fd = io.popen("/usr/sbin/nlbw -c list") + local periods = { } + + if fd then + while true do + local period = fd:read("*l") + + if not period then + break + end + + periods[#periods+1] = period + end + + fd:close() + end + + http.prepare_content("application/json") + http.write_json(periods) +end + +function action_ptr(...) + local http = require "luci.http" + local util = require "luci.util" + + http.prepare_content("application/json") + http.write_json(util.ubus("network.rrdns", "lookup", { + addrs = {...}, timeout = 3000 + })) +end + +function action_download() + local nixio = require "nixio" + local http = require "luci.http" + local sys = require "luci.sys" + local uci = require "luci.model.uci".cursor() + + local dir = uci:get_first("nlbwmon", "nlbwmon", "database_directory") + or "/var/lib/nlbwmon" + + if dir and nixio.fs.stat(dir, "type") == "dir" then + local n = "nlbwmon-backup-%s-%s.tar.gz" + %{ sys.hostname(), os.date("%Y-%m-%d") } + + http.prepare_content("application/octet-stream") + http.header("Content-Disposition", "attachment; filename=\"%s\"" % n) + exec("/bin/tar", { "-C", dir, "-c", "-z", ".", "-f", "-" }, http.write) + else + http.status(500, "Unable to find database directory") + end +end + +function action_restore() + local nixio = require "nixio" + local http = require "luci.http" + local i18n = require "luci.i18n" + local tpl = require "luci.template" + local uci = require "luci.model.uci".cursor() + + local tmp = "/tmp/nlbw-restore.tar.gz" + local dir = uci:get_first("nlbwmon", "nlbwmon", "database_directory") + or "/var/lib/nlbwmon" + + local fp + http.setfilehandler( + function(meta, chunk, eof) + if not fp and meta and meta.name == "archive" then + fp = io.open(tmp, "w") + end + if fp and chunk then + fp:write(chunk) + end + if fp and eof then + fp:close() + end + end) + + local files = { } + local tar = io.popen("/bin/tar -tzf %s" % tmp, "r") + if tar then + while true do + local file = tar:read("*l") + if not file then + break + elseif file:match("^%d%d%d%d%d%d%d%d%.db%.gz$") or + file:match("^%./%d%d%d%d%d%d%d%d%.db%.gz$") then + files[#files+1] = file + end + end + tar:close() + end + + if #files == 0 then + http.status(500, "Internal Server Error") + tpl.render("nlbw/backup", { + message = i18n.translate("Invalid or empty backup archive") + }) + return + end + + + local output = { } + + exec("/etc/init.d/nlbwmon", { "stop" }) + exec("/bin/mkdir", { "-p", dir }) + + exec("/bin/tar", { "-C", dir, "-vxzf", tmp, unpack(files) }, + function(chunk) output[#output+1] = chunk:match("%S+") end) + + exec("/bin/rm", { "-f", tmp }) + exec("/etc/init.d/nlbwmon", { "start" }) + + tpl.render("nlbw/backup", { + message = i18n.translatef( + "The following database files have been restored: %s", + table.concat(output, ", ")) + }) +end |