summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-statistics
diff options
context:
space:
mode:
Diffstat (limited to 'applications/luci-statistics')
-rwxr-xr-xapplications/luci-statistics/root/usr/bin/stat-genconfig6
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool.lua171
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool/colors.lua14
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool/definitions/cpu/cpu.lua2
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool/definitions/netlink.lua163
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool/definitions/ping/ping.lua23
-rw-r--r--applications/luci-statistics/src/statistics/rrdtool/definitions/wireless.lua2
-rw-r--r--applications/luci-statistics/src/view/public_statistics/graph.htm2
8 files changed, 296 insertions, 87 deletions
diff --git a/applications/luci-statistics/root/usr/bin/stat-genconfig b/applications/luci-statistics/root/usr/bin/stat-genconfig
index cd707c6b2..39532ca07 100755
--- a/applications/luci-statistics/root/usr/bin/stat-genconfig
+++ b/applications/luci-statistics/root/usr/bin/stat-genconfig
@@ -294,6 +294,12 @@ plugins = {
network = config_network,
+ ping = {
+ { "TTL" },
+ { },
+ { "Hosts" }
+ },
+
processes = {
{ },
{ },
diff --git a/applications/luci-statistics/src/statistics/rrdtool.lua b/applications/luci-statistics/src/statistics/rrdtool.lua
index 56894eb6c..97772cc38 100644
--- a/applications/luci-statistics/src/statistics/rrdtool.lua
+++ b/applications/luci-statistics/src/statistics/rrdtool.lua
@@ -66,7 +66,20 @@ function Graph._clearargs( self )
end
end
+function Graph._forcelol( self, list )
+ if type(list[1]) ~= "table" then
+ return( { list } )
+ end
+ return( list )
+end
+
function Graph._rrdtool( self, png, rrd )
+
+ -- prepare directory
+ local dir = png:gsub("/[^/]+$","")
+ ffluci.fs.mkdir( dir, true )
+
+ -- construct commandline
local cmdline = "rrdtool graph " .. png
for i, opt in ipairs(self.args) do
@@ -84,93 +97,93 @@ function Graph._rrdtool( self, png, rrd )
end
end
+ -- execute rrdtool
local rrdtool = io.popen( cmdline )
- rrdtool:read("*a")
rrdtool:close()
end
-function Graph._generic( self, optlist )
+function Graph._generic( self, opts )
local images = { }
- if type(optlist[1]) ~= "table" then
- optlist = { optlist }
- end
+ -- remember images
+ table.insert( images, opts.image )
- for i, opts in ipairs(optlist) do
- -- remember images
- table.insert( images, opts.image )
+ -- insert provided addition rrd options
+ self:_push( { "-t", opts.title or "Unknown title" } )
+ self:_push( opts.rrd )
- -- insert provided addition rrd options
- self:_push( { "-t", opts.title or "Unknown title" } )
- self:_push( opts.rrd )
+ -- construct an array of safe instance names
+ local inst_names = { }
+ for i, source in ipairs(opts.sources) do
+ inst_names[i] = i .. source.name:gsub("[^A-Za-z0-9%-_]","_")
+ end
- -- construct an array of safe instance names
- local inst_names = { }
- for i, source in ipairs(opts.sources) do
- inst_names[i] = i .. source.name:gsub("[^A-Za-z0-9%-_]","_")
+ -- create DEF statements for each instance, find longest instance name
+ local longest_name = 0
+ for i, source in ipairs(opts.sources) do
+ if source.name:len() > longest_name then
+ longest_name = source.name:len()
end
- -- create DEF statements for each instance, find longest instance name
- local longest_name = 0
- for i, source in ipairs(opts.sources) do
- if source.name:len() > longest_name then
- longest_name = source.name:len()
- end
+ local ds = source.ds or "value"
- self:_push( "DEF:" .. inst_names[i] .. "_min=" ..source.rrd .. ":value:MIN" )
- self:_push( "DEF:" .. inst_names[i] .. "_avg=" ..source.rrd .. ":value:AVERAGE" )
- self:_push( "DEF:" .. inst_names[i] .. "_max=" ..source.rrd .. ":value:MAX" )
- self:_push( "CDEF:" .. inst_names[i] .. "_nnl=" .. inst_names[i] .. "_avg,UN,0," .. inst_names[i] .. "_avg,IF" )
- end
+ self:_push( "DEF:" .. inst_names[i] .. "_min=" ..source.rrd .. ":" .. ds .. ":MIN" )
+ self:_push( "DEF:" .. inst_names[i] .. "_avg=" ..source.rrd .. ":" .. ds .. ":AVERAGE" )
+ self:_push( "DEF:" .. inst_names[i] .. "_max=" ..source.rrd .. ":" .. ds .. ":MAX" )
+ self:_push( "CDEF:" .. inst_names[i] .. "_nnl=" .. inst_names[i] .. "_avg,UN,0," .. inst_names[i] .. "_avg,IF" )
+ end
- -- create CDEF statement for last instance name
- self:_push( "CDEF:" .. inst_names[#inst_names] .. "_stk=" .. inst_names[#inst_names] .. "_nnl" )
-
- -- create CDEF statements for each instance
- for i, source in ipairs(inst_names) do
- if i > 1 then
- self:_push(
- "CDEF:" ..
- inst_names[1 + #inst_names - i] .. "_stk=" ..
- inst_names[1 + #inst_names - i] .. "_nnl," ..
- inst_names[2 + #inst_names - i] .. "_stk,+"
- )
- end
+ -- create CDEF statement for last instance name
+ self:_push( "CDEF:" .. inst_names[#inst_names] .. "_stk=" .. inst_names[#inst_names] .. "_nnl" )
+
+ -- create CDEF statements for each instance
+ for i, source in ipairs(inst_names) do
+ if i > 1 then
+ self:_push(
+ "CDEF:" ..
+ inst_names[1 + #inst_names - i] .. "_stk=" ..
+ inst_names[1 + #inst_names - i] .. "_nnl," ..
+ inst_names[2 + #inst_names - i] .. "_stk,+"
+ )
end
+ end
- -- create LINE and GPRINT statements for each instance
- for i, source in ipairs(opts.sources) do
+ -- create LINE and GPRINT statements for each instance
+ for i, source in ipairs(opts.sources) do
- local legend = string.format(
- "%-" .. longest_name .. "s",
- source.name
- )
+ local legend = string.format(
+ "%-" .. longest_name .. "s",
+ source.name
+ )
- local numfmt = opts.number_format or "%6.1lf"
+ local numfmt = opts.number_format or "%6.1lf"
- local line_color
- local area_color
+ local line_color
+ local area_color
- if type(opts.colors[source.name]) == "string" then
- line_color = opts.colors[source.name]
- area_color = self.colors:from_string( line_color )
- else
- area_color = self.colors:random()
- line_color = self.colors:to_string( area_color )
- end
+ -- find color: try source, then opts.colors; fall back to random color
+ if type(source.color) == "string" then
+ line_color = source.color
+ area_color = self.colors:from_string( line_color )
+ elseif type(opts.colors[source.name:gsub("[^%w]","_")]) == "string" then
+ line_color = opts.colors[source.name:gsub("[^%w]","_")]
+ area_color = self.colors:from_string( line_color )
+ else
+ area_color = self.colors:random()
+ line_color = self.colors:to_string( area_color )
+ end
- area_color = self.colors:to_string(
- self.colors:faded( area_color )
- )
+ -- derive area background color from line color
+ area_color = self.colors:to_string( self.colors:faded( area_color ) )
- self:_push( "AREA:" .. inst_names[i] .. "_stk#" .. area_color )
- self:_push( "LINE1:" .. inst_names[i] .. "_stk#" .. line_color .. ":" .. legend )
- self:_push( "GPRINT:" .. inst_names[i] .. "_min:MIN:" .. numfmt .. " Min" )
- self:_push( "GPRINT:" .. inst_names[i] .. "_avg:AVERAGE:" .. numfmt .. " Avg" )
- self:_push( "GPRINT:" .. inst_names[i] .. "_max:MAX:" .. numfmt .. " Max" )
- self:_push( "GPRINT:" .. inst_names[i] .. "_avg:LAST:" .. numfmt .. " Last\\l" )
- end
+
+ self:_push( "AREA:" .. inst_names[i] .. "_stk#" .. area_color )
+ self:_push( "LINE1:" .. inst_names[i] .. "_stk#" .. line_color .. ":" .. legend )
+ self:_push( "GPRINT:" .. inst_names[i] .. "_min:MIN:" .. numfmt .. " Min" )
+ self:_push( "GPRINT:" .. inst_names[i] .. "_avg:AVERAGE:" .. numfmt .. " Avg" )
+ self:_push( "GPRINT:" .. inst_names[i] .. "_max:MAX:" .. numfmt .. " Max" )
+ self:_push( "GPRINT:" .. inst_names[i] .. "_avg:LAST:" .. numfmt .. " Last\\l" )
end
return images
@@ -186,14 +199,16 @@ function Graph.render( self, host, plugin, plugin_instance )
local stat, def = pcall( require, plugin_def )
if stat and def and type(def.rrdargs) == "function" then
- for i, png in ipairs( self:_generic( def.rrdargs( self, host, plugin, plugin_instance, dtype ) ) ) do
- table.insert( pngs, png )
+ for i, opts in ipairs( self:_forcelol( def.rrdargs( self, host, plugin, plugin_instance, dtype ) ) ) do
+ for i, png in ipairs( self:_generic( opts ) ) do
+ table.insert( pngs, png )
- -- exec
- self:_rrdtool( png )
+ -- exec
+ self:_rrdtool( png )
- -- clear args
- self:_clearargs()
+ -- clear args
+ self:_clearargs()
+ end
end
else
@@ -205,14 +220,16 @@ function Graph.render( self, host, plugin, plugin_instance )
local stat, def = pcall( require, dtype_def )
if stat and def and type(def.rrdargs) == "function" then
- for i, png in ipairs( self:_generic( def.rrdargs( self, host, plugin, plugin_instance, dtype ) ) ) do
- table.insert( pngs, png )
+ for i, opts in ipairs( self:_forcelol( def.rrdargs( self, host, plugin, plugin_instance, dtype ) ) ) do
+ for i, png in ipairs( self:_generic( opts ) ) do
+ table.insert( pngs, png )
- -- exec
- self:_rrdtool( png )
+ -- exec
+ self:_rrdtool( png )
- -- clear args
- self:_clearargs()
+ -- clear args
+ self:_clearargs()
+ end
end
else
diff --git a/applications/luci-statistics/src/statistics/rrdtool/colors.lua b/applications/luci-statistics/src/statistics/rrdtool/colors.lua
index f1cec1f22..cd1e52d19 100644
--- a/applications/luci-statistics/src/statistics/rrdtool/colors.lua
+++ b/applications/luci-statistics/src/statistics/rrdtool/colors.lua
@@ -24,15 +24,15 @@ function Instance.to_string( self, c )
end
function Instance.random( self )
- local r = math.random(256)
- local g = math.random(256)
- local min = 1
- local max = 256
+ local r = math.random(255)
+ local g = math.random(255)
+ local min = 0
+ local max = 255
- if ( r + g ) < 256 then
- min = 256 - r - g
+ if ( r + g ) < 255 then
+ min = 255 - r - g
else
- max = 512 - r - g
+ max = 511 - r - g
end
local b = min + math.floor( math.random() * ( max - min ) )
diff --git a/applications/luci-statistics/src/statistics/rrdtool/definitions/cpu/cpu.lua b/applications/luci-statistics/src/statistics/rrdtool/definitions/cpu/cpu.lua
index fad7fd2a4..557c5dafe 100644
--- a/applications/luci-statistics/src/statistics/rrdtool/definitions/cpu/cpu.lua
+++ b/applications/luci-statistics/src/statistics/rrdtool/definitions/cpu/cpu.lua
@@ -7,7 +7,7 @@ function rrdargs( graph, host, plugin, plugin_instance, dtype )
opts = { }
opts.sources = { }
opts.image = graph:mkpngpath( host, plugin, plugin_instance, dtype )
- opts.title = graph:mktitle( host, plugin, plugin_instance, dtype )
+ opts.title = host .. ": Prozessorauslastung"
opts.rrd = { "-v", "Percent" }
opts.colors = {
idle = 'ffffff',
diff --git a/applications/luci-statistics/src/statistics/rrdtool/definitions/netlink.lua b/applications/luci-statistics/src/statistics/rrdtool/definitions/netlink.lua
new file mode 100644
index 000000000..de3924dc7
--- /dev/null
+++ b/applications/luci-statistics/src/statistics/rrdtool/definitions/netlink.lua
@@ -0,0 +1,163 @@
+module("ffluci.statistics.rrdtool.definitions.netlink", package.seeall)
+
+function rrdargs( graph, host, plugin, plugin_instance )
+
+ local diagram_list = { }
+
+ -- diagram names
+ local dtypes_names = {
+ "Pakete",
+ "Paketkollisionen",
+ "Paketfehler",
+ "Verkehr",
+ "RX-Fehler",
+ "TX-Fehler"
+ }
+
+ -- diagram units
+ local dtypes_units = {
+ "Pakete/s",
+ "Kollisionen/s",
+ "Fehler/s", -- (?)
+ "Bytes/s",
+ "Fehler/s",
+ "Fehler/s"
+ }
+
+ -- data source overrides
+ local dtypes_sources = {
+ if_errors = { "rx", "tx" }, -- if_errors has rx and tx
+ if_octets = { "rx", "tx" } -- if_octets has rx and tx
+ }
+
+ -- diagram data types
+ local dtypes_list = {
+
+ -- diagram 1: combined interface packet statistics
+ {
+ if_dropped = { "" }, -- packets/s
+ if_multicast = { "" }, -- packets/s
+ if_packets = { "" } -- packets/s
+ },
+
+ -- diagram 2: interface collision statistics
+ {
+ if_collisions = { "" } -- collisions/s
+ },
+
+ -- diagram 3: interface error statistics
+ {
+ if_errors = { "" } -- errors/s (?)
+ },
+
+ -- diagram 4: interface traffic statistics
+ {
+ if_octets = { "" } -- bytes/s
+ },
+
+ -- diagram 5: interface rx error statistics
+ {
+ if_rx_errors = { -- errors/s
+ "length", "missed", "over", "crc", "fifo", "frame"
+ }
+ },
+
+ -- diagram 6: interface tx error statistics
+ {
+ if_tx_errors = { -- errors/s
+ "aborted", "carrier", "fifo", "heartbeat", "window"
+ }
+ }
+ }
+
+ -- diagram colors
+ local dtypes_colors = {
+
+ -- diagram 1
+ {
+ if_dropped = "ff0000",
+ if_multicast = "0000ff",
+ if_packets = "00ff00"
+ },
+
+ -- diagram 2
+ {
+ if_collisions = "ff0000"
+ },
+
+ -- diagram 3
+ {
+ if_errors__tx_ = "ff0000",
+ if_errors__rx_ = "ff5500"
+ },
+
+ -- diagram 4
+ {
+ if_octets__tx_ = "00ff00",
+ if_octets__rx_ = "0000ff"
+ },
+
+ -- diagram 5
+ {
+ length = "0000ff",
+ missed = "ff5500",
+ over = "ff0066",
+ crc = "ff0000",
+ fifo = "00ff00",
+ frame = "ffff00"
+ },
+
+ -- diagram 6
+ {
+ aborted = "ff0000",
+ carrier = "ffff00",
+ fifo = "00ff00",
+ heartbeat = "0000ff",
+ window = "8800ff"
+ }
+ }
+
+
+ for i, name in ipairs(dtypes_names) do
+
+ local dtypes = dtypes_list[i]
+ local opts = { }
+
+ opts.sources = { }
+ opts.image = graph:mkpngpath( host, plugin, plugin_instance, "netlink" .. i )
+ opts.title = host .. ": Netlink Statistiken - " .. name .. " auf " .. plugin_instance
+ opts.rrd = { "-v", dtypes_units[i] }
+ opts.colors = dtypes_colors[i]
+
+ for dtype, dinstances in pairs(dtypes) do
+ for i, inst in ipairs(dinstances) do
+
+ local name = inst
+ if name:len() == 0 then name = dtype end
+
+ -- check for data source override
+ if dtypes_sources[dtype] then
+
+ -- has override
+ for i, ds in ipairs(dtypes_sources[dtype]) do
+ table.insert( opts.sources, {
+ ds = ds, -- override
+ name = name .. " (" .. ds .. ")",
+ rrd = graph:mkrrdpath( host, plugin, plugin_instance, dtype, inst )
+ } )
+ end
+ else
+ -- no override, assume single "value" data source
+ table.insert( opts.sources, {
+ name = name,
+ rrd = graph:mkrrdpath( host, plugin, plugin_instance, dtype, inst )
+ } )
+ end
+ end
+ end
+
+ table.insert( diagram_list, opts )
+ end
+
+ return diagram_list
+end
diff --git a/applications/luci-statistics/src/statistics/rrdtool/definitions/ping/ping.lua b/applications/luci-statistics/src/statistics/rrdtool/definitions/ping/ping.lua
new file mode 100644
index 000000000..48a5673ad
--- /dev/null
+++ b/applications/luci-statistics/src/statistics/rrdtool/definitions/ping/ping.lua
@@ -0,0 +1,23 @@
+module("ffluci.statistics.rrdtool.definitions.ping.ping", package.seeall)
+
+function rrdargs( graph, host, plugin, plugin_instance, dtype )
+
+ dtype_instances = graph.tree:data_instances( plugin, plugin_instance, dtype )
+
+ opts = { }
+ opts.sources = { }
+ opts.image = graph:mkpngpath( host, plugin, plugin_instance, dtype )
+ opts.title = host .. ": Pingzeiten"
+ opts.rrd = { "-v", "Millisekunden" }
+ opts.colors = { }
+
+ for i, inst in ipairs(dtype_instances) do
+ opts.sources[i] = {
+ ds = "ping",
+ name = inst,
+ rrd = graph:mkrrdpath( host, plugin, plugin_instance, dtype, inst )
+ }
+ end
+
+ return opts
+end
diff --git a/applications/luci-statistics/src/statistics/rrdtool/definitions/wireless.lua b/applications/luci-statistics/src/statistics/rrdtool/definitions/wireless.lua
index 016f1f465..5b3acc51f 100644
--- a/applications/luci-statistics/src/statistics/rrdtool/definitions/wireless.lua
+++ b/applications/luci-statistics/src/statistics/rrdtool/definitions/wireless.lua
@@ -7,7 +7,7 @@ function rrdargs( graph, host, plugin, plugin_instance )
opts = { }
opts.sources = { }
opts.image = graph:mkpngpath( host, plugin, plugin_instance, "wireless" )
- opts.title = graph:mktitle( host, plugin, plugin_instance, "wireless" )
+ opts.title = host .. ": WLAN Signal"
opts.rrd = { "-v", "dBm" }
opts.colors = {
signal_power = '0000ff',
diff --git a/applications/luci-statistics/src/view/public_statistics/graph.htm b/applications/luci-statistics/src/view/public_statistics/graph.htm
index d0da883d6..093d76d0e 100644
--- a/applications/luci-statistics/src/view/public_statistics/graph.htm
+++ b/applications/luci-statistics/src/view/public_statistics/graph.htm
@@ -1,6 +1,6 @@
<%+header%>
-<h1>Statistik (<%=request%>)</h1>
+<h1>Statistik</h1>
<% for i, img in ipairs(images) do %>
<img src="<%=img:gsub("/tmp/rrdimg/OpenWrt","/img")%>" />