* luci/statistics: added diagram models for process and df plugins, adept controller to recent luci core, support models with per instance diagrams and index diagrams, added new strings to language file
This commit is contained in:
parent
d5c47776a5
commit
d8ba05412c
5 changed files with 193 additions and 29 deletions
|
@ -1,27 +1,40 @@
|
||||||
module("luci.controller.luci_statistics.luci_statistics", package.seeall)
|
module("luci.controller.luci_statistics.luci_statistics", package.seeall)
|
||||||
|
|
||||||
local fs = require("luci.fs")
|
require("luci.fs")
|
||||||
local i18n = require("luci.i18n")
|
require("luci.i18n")
|
||||||
local tpl = require("luci.template")
|
require("luci.template")
|
||||||
local rrd = require("luci.statistics.rrdtool")
|
|
||||||
local data = require("luci.statistics.datatree").Instance()
|
|
||||||
|
|
||||||
function index()
|
function index()
|
||||||
|
|
||||||
-- XXX: fixme
|
require("luci.i18n")
|
||||||
i18n.load("statistics.en")
|
require("luci.statistics.datatree")
|
||||||
|
|
||||||
|
-- load language file
|
||||||
|
luci.i18n.load("statistics.en")
|
||||||
|
|
||||||
|
-- get rrd data tree
|
||||||
|
local tree = luci.statistics.datatree.Instance()
|
||||||
|
|
||||||
|
-- override entry(): check for existance <plugin>.so where <plugin> is derived from the called path
|
||||||
function _entry( path, ... )
|
function _entry( path, ... )
|
||||||
local file = path[4] or path[3]
|
local file = path[4] or path[3]
|
||||||
if fs.isfile( "/usr/lib/collectd/" .. file .. ".so" ) then
|
if luci.fs.isfile( "/usr/lib/collectd/" .. file .. ".so" ) then
|
||||||
entry( path, ... )
|
entry( path, ... )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function _i18n( str )
|
-- override call(): call requested action function with supplied parameters
|
||||||
return i18n.translate( "stat_" .. str, str )
|
function _call( func, tree, plugin )
|
||||||
|
return function() getfenv()[func]( tree, plugin ) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- override i18n(): try to translate stat_<str> or fall back to <str>
|
||||||
|
function _i18n( str )
|
||||||
|
return luci.i18n.translate( "stat_" .. str, str )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
entry({"admin", "statistics"}, call("statistics_index"), "Statistiken", 80)
|
entry({"admin", "statistics"}, call("statistics_index"), "Statistiken", 80)
|
||||||
entry({"admin", "statistics", "collectd"}, cbi("luci_statistics/collectd"), "Collectd", 10)
|
entry({"admin", "statistics", "collectd"}, cbi("luci_statistics/collectd"), "Collectd", 10)
|
||||||
|
|
||||||
|
@ -52,10 +65,10 @@ function index()
|
||||||
-- public views
|
-- public views
|
||||||
entry({"freifunk", "statistics"}, call("statistics_index"), "Statistiken", 80).i18n = "statistics"
|
entry({"freifunk", "statistics"}, call("statistics_index"), "Statistiken", 80).i18n = "statistics"
|
||||||
|
|
||||||
for i, plugin in ipairs( data:plugins() ) do
|
for i, plugin in ipairs( tree:plugins() ) do
|
||||||
|
|
||||||
-- get plugin instances
|
-- get plugin instances
|
||||||
local instances = data:plugin_instances( plugin )
|
local instances = tree:plugin_instances( plugin )
|
||||||
|
|
||||||
-- plugin menu entry
|
-- plugin menu entry
|
||||||
_entry( { "freifunk", "statistics", plugin }, call("statistics_render"), _i18n( plugin ), i )
|
_entry( { "freifunk", "statistics", plugin }, call("statistics_render"), _i18n( plugin ), i )
|
||||||
|
@ -64,7 +77,10 @@ function index()
|
||||||
if #instances > 1 then
|
if #instances > 1 then
|
||||||
for j, inst in ipairs(instances) do
|
for j, inst in ipairs(instances) do
|
||||||
-- instance menu entry
|
-- instance menu entry
|
||||||
entry( { "freifunk", "statistics", plugin, inst }, call("statistics_render"), inst, j )
|
entry(
|
||||||
|
{ "freifunk", "statistics", plugin, inst },
|
||||||
|
call("statistics_render"), inst, j
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -72,7 +88,7 @@ end
|
||||||
|
|
||||||
|
|
||||||
function statistics_index()
|
function statistics_index()
|
||||||
tpl.render("admin_statistics/index")
|
luci.template.render("admin_statistics/index")
|
||||||
end
|
end
|
||||||
|
|
||||||
function statistics_outputplugins()
|
function statistics_outputplugins()
|
||||||
|
@ -83,7 +99,7 @@ function statistics_outputplugins()
|
||||||
csv="CSV"
|
csv="CSV"
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl.render("admin_statistics/outputplugins", {plugins=plugins})
|
luci.template.render("admin_statistics/outputplugins", {plugins=plugins})
|
||||||
end
|
end
|
||||||
|
|
||||||
function statistics_systemplugins()
|
function statistics_systemplugins()
|
||||||
|
@ -95,7 +111,7 @@ function statistics_systemplugins()
|
||||||
processes="Prozesse"
|
processes="Prozesse"
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl.render("admin_statistics/systemplugins", {plugins=plugins})
|
luci.template.render("admin_statistics/systemplugins", {plugins=plugins})
|
||||||
end
|
end
|
||||||
|
|
||||||
function statistics_networkplugins()
|
function statistics_networkplugins()
|
||||||
|
@ -108,41 +124,54 @@ function statistics_networkplugins()
|
||||||
dns="DNS"
|
dns="DNS"
|
||||||
}
|
}
|
||||||
|
|
||||||
tpl.render("admin_statistics/networkplugins", {plugins=plugins})
|
luci.template.render("admin_statistics/networkplugins", {plugins=plugins})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function statistics_render()
|
function statistics_render( tree )
|
||||||
local plugin = luci.dispatcher.request[3]
|
|
||||||
local instances = { luci.dispatcher.request[4] }
|
require("luci.statistics.rrdtool")
|
||||||
|
require("luci.template")
|
||||||
|
|
||||||
|
local req = luci.dispatcher.request
|
||||||
|
local graph = luci.statistics.rrdtool.Graph()
|
||||||
|
|
||||||
|
local plugin = req[3]
|
||||||
|
local instances = { req[4] }
|
||||||
local images = { }
|
local images = { }
|
||||||
|
|
||||||
-- no instance requested, find all instances
|
-- no instance requested, find all instances
|
||||||
if #instances == 0 then
|
if #instances == 0 then
|
||||||
|
|
||||||
instances = data:plugin_instances( plugin )
|
instances = graph.tree:plugin_instances( plugin )
|
||||||
|
|
||||||
-- more than one available instance
|
-- more than one available instance
|
||||||
if #instances > 1 then
|
if #instances > 1 then
|
||||||
|
|
||||||
-- redirect to first instance and return
|
-- redirect to first instance and return
|
||||||
local r = luci.dispatcher.request
|
local r = luci.dispatcher.request
|
||||||
|
local i = instances[1]
|
||||||
|
if i:len() == 0 then i = "-" end
|
||||||
|
|
||||||
luci.http.redirect( luci.dispatcher.build_url(
|
luci.http.redirect( luci.dispatcher.build_url(
|
||||||
r[1], r[2], r[3], instances[1]
|
req[1], req[2], req[3], i
|
||||||
) )
|
) )
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- index instance requested
|
||||||
|
elseif instances[1] == "-" then
|
||||||
|
instances[1] = ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- render graphs
|
-- render graphs
|
||||||
for i, inst in ipairs( instances ) do
|
for i, inst in ipairs( instances ) do
|
||||||
local graph = rrd.Graph()
|
|
||||||
for i, img in ipairs( graph:render( plugin, inst ) ) do
|
for i, img in ipairs( graph:render( plugin, inst ) ) do
|
||||||
table.insert( images, img )
|
table.insert( images, img )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
tpl.render("public_statistics/graph", { images=images, plugin=plugin } )
|
luci.template.render("public_statistics/graph", { images=images, plugin=plugin } )
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ stat_processes = "Processes"
|
||||||
stat_wireless = "Wireless"
|
stat_wireless = "Wireless"
|
||||||
stat_tcpconns = "TCP Connections"
|
stat_tcpconns = "TCP Connections"
|
||||||
stat_interface = "Interfaces"
|
stat_interface = "Interfaces"
|
||||||
|
stat_df = "Disk Space Usage"
|
||||||
|
|
||||||
-- diagrams
|
-- diagrams
|
||||||
stat_dg_title_wireless__signal_noise = "%H: Wireless - Signal Noise Ratio"
|
stat_dg_title_wireless__signal_noise = "%H: Wireless - Signal Noise Ratio"
|
||||||
|
@ -53,6 +54,23 @@ stat_dg_title_processes = "%H: Processes"
|
||||||
stat_dg_label_processes = "Processes/s"
|
stat_dg_label_processes = "Processes/s"
|
||||||
stat_ds_ps_state = "%di"
|
stat_ds_ps_state = "%di"
|
||||||
|
|
||||||
|
stat_dg_title_processes__ps_cputime = "%H: Process %pi - used cpu time"
|
||||||
|
stat_dg_label_processes__ps_cputime = "Jiffies"
|
||||||
|
stat_ds_ps_cputime__syst = "system"
|
||||||
|
stat_ds_ps_cputime__user = "user"
|
||||||
|
|
||||||
|
stat_dg_title_processes__ps_count = "%H: Process %pi - threads and processes"
|
||||||
|
stat_dg_label_processes__ps_count = "Count"
|
||||||
|
stat_ds_ps_count = "%ds"
|
||||||
|
|
||||||
|
stat_dg_title_processes__ps_pagefaults = "%H: Process %pi - page faults"
|
||||||
|
stat_dg_label_processes__ps_pagefaults = "Pagefaults"
|
||||||
|
stat_ds_ps_pagefaults = "page faults"
|
||||||
|
|
||||||
|
stat_dg_title_processes__ps_rss = "%H: Process %pi - virtual memory size"
|
||||||
|
stat_dg_label_processes__ps_rss = "Bytes"
|
||||||
|
stat_ds_ps_rss = "virtual memory"
|
||||||
|
|
||||||
stat_dg_title_cpu = "%H: Usage on Processor #%pi"
|
stat_dg_title_cpu = "%H: Usage on Processor #%pi"
|
||||||
stat_dg_label_cpu = "%"
|
stat_dg_label_cpu = "%"
|
||||||
stat_ds_cpu = "%di"
|
stat_ds_cpu = "%di"
|
||||||
|
@ -66,3 +84,9 @@ stat_dg_label_interface__if_packets = "Packets/s"
|
||||||
stat_dg_title_tcpconns = "%H: TCP-Connections to Port %pi"
|
stat_dg_title_tcpconns = "%H: TCP-Connections to Port %pi"
|
||||||
stat_dg_label_tcpconns = "Connections/s"
|
stat_dg_label_tcpconns = "Connections/s"
|
||||||
stat_ds_tcp_connections = "%di"
|
stat_ds_tcp_connections = "%di"
|
||||||
|
|
||||||
|
stat_dg_title_df = "%H: Disk Space Usage on %di"
|
||||||
|
stat_dg_label_df = "Bytes"
|
||||||
|
stat_ds_df__free = "%ds"
|
||||||
|
stat_ds_df__used = "%ds"
|
||||||
|
|
||||||
|
|
|
@ -419,7 +419,6 @@ function Graph._generic( self, opts, plugin, plugin_instance, dtype, index )
|
||||||
for i, instance in ipairs(instances) do
|
for i, instance in ipairs(instances) do
|
||||||
|
|
||||||
-- store title and vlabel
|
-- store title and vlabel
|
||||||
-- XXX: i18n
|
|
||||||
_ti( _args, "-t" )
|
_ti( _args, "-t" )
|
||||||
_ti( _args, opts.title or self.i18n:title( plugin, plugin_instance, _sources[1].type, instance ) )
|
_ti( _args, opts.title or self.i18n:title( plugin, plugin_instance, _sources[1].type, instance ) )
|
||||||
_ti( _args, "-v" )
|
_ti( _args, "-v" )
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
module("luci.statistics.rrdtool.definitions.df.df", package.seeall)
|
||||||
|
|
||||||
|
function rrdargs( graph, plugin, plugin_instance, dtype )
|
||||||
|
|
||||||
|
return {
|
||||||
|
per_instance = true,
|
||||||
|
number_format = "%5.1lf%s",
|
||||||
|
|
||||||
|
data = {
|
||||||
|
sources = {
|
||||||
|
df = { "free", "used" }
|
||||||
|
},
|
||||||
|
|
||||||
|
options = {
|
||||||
|
df__free = {
|
||||||
|
color = "00ff00"
|
||||||
|
},
|
||||||
|
|
||||||
|
df__used = {
|
||||||
|
color = "ff0000",
|
||||||
|
flip = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
|
@ -0,0 +1,86 @@
|
||||||
|
module("luci.statistics.rrdtool.definitions.processes", package.seeall)
|
||||||
|
|
||||||
|
function rrdargs( graph, plugin, plugin_instance )
|
||||||
|
|
||||||
|
if plugin_instance == "" then
|
||||||
|
return {
|
||||||
|
data = {
|
||||||
|
instances = {
|
||||||
|
ps_state = {
|
||||||
|
"sleeping", "running", "paging", "blocked", "stopped", "zombies"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ps_state_sleeping = { color = "0000ff" },
|
||||||
|
ps_state_running = { color = "008000" },
|
||||||
|
ps_state_paging = { color = "ffff00" },
|
||||||
|
ps_state_blocked = { color = "ff5000" },
|
||||||
|
ps_state_stopped = { color = "555555" },
|
||||||
|
ps_state_zombies = { color = "ff0000" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {
|
||||||
|
|
||||||
|
{
|
||||||
|
data = {
|
||||||
|
sources = {
|
||||||
|
ps_cputime = { "syst", "user" }
|
||||||
|
},
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ps_cputime__user = {
|
||||||
|
color = "0000ff",
|
||||||
|
overlay = true
|
||||||
|
},
|
||||||
|
|
||||||
|
ps_cputime__syst = {
|
||||||
|
color = "ff0000",
|
||||||
|
overlay = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
data = {
|
||||||
|
sources = {
|
||||||
|
ps_count = { "threads", "processes" }
|
||||||
|
},
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ps_count__threads = { color = "00ff00" },
|
||||||
|
ps_count__processes = { color = "0000bb" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
data = {
|
||||||
|
sources = {
|
||||||
|
ps_pagefaults = { "minflt", "majflt" }
|
||||||
|
},
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ps_pagefaults__minflt = { color = "ff0000" },
|
||||||
|
ps_pagefaults__majflt = { color = "ff5500" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
number_format = "%5.1lf%s",
|
||||||
|
|
||||||
|
data = {
|
||||||
|
types = { "ps_rss" },
|
||||||
|
|
||||||
|
options = {
|
||||||
|
ps_rss = { color = "0000ff" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue