diff options
Diffstat (limited to 'applications/luci-statistics/src/statistics/rrdtool.lua')
-rw-r--r-- | applications/luci-statistics/src/statistics/rrdtool.lua | 264 |
1 files changed, 0 insertions, 264 deletions
diff --git a/applications/luci-statistics/src/statistics/rrdtool.lua b/applications/luci-statistics/src/statistics/rrdtool.lua deleted file mode 100644 index b399866a85..0000000000 --- a/applications/luci-statistics/src/statistics/rrdtool.lua +++ /dev/null @@ -1,264 +0,0 @@ -module("luci.statistics.rrdtool", package.seeall) - -require("luci.statistics.datatree") -require("luci.statistics.rrdtool.colors") -require("luci.statistics.rrdtool.definitions") -require("luci.util") -require("luci.bits") -require("luci.fs") - - -Graph = luci.util.class() - -function Graph.__init__( self, timespan, opts ) - - opts = opts or { } - opts.width = opts.width or "400" - - self.colors = luci.statistics.rrdtool.colors.Instance() - self.defs = luci.statistics.rrdtool.definitions.Instance() - self.tree = luci.statistics.datatree.Instance() - - -- rrdtool defalt args - self.args = { - "-a", "PNG", - "-s", "NOW-" .. ( timespan or 900 ), - "-w", opts.width - } -end - -function Graph.mktitle( self, host, plugin, plugin_instance, dtype, dtype_instance ) - local t = host .. "/" .. plugin - if type(plugin_instance) == "string" and plugin_instance:len() > 0 then - t = t .. "-" .. plugin_instance - end - t = t .. "/" .. dtype - if type(dtype_instance) == "string" and dtype_instance:len() > 0 then - t = t .. "-" .. dtype_instance - end - return t -end - -function Graph.mkrrdpath( self, ... ) - return string.format( "/tmp/%s.rrd", self:mktitle( ... ) ) -end - -function Graph.mkpngpath( self, ... ) - return string.format( "/tmp/rrdimg/%s.png", self:mktitle( ... ) ) -end - -function Graph._push( self, elem ) - - if type(elem) == "string" then - table.insert( self.args, elem ) - else - for i, item in ipairs(elem) do - table.insert( self.args, item ) - end - end - - return( self.args ) -end - -function Graph._clearargs( self ) - for i = #self.args, 7, -1 do - table.remove( self.args, i ) - 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("/[^/]+$","") - luci.fs.mkdir( dir, true ) - - -- construct commandline - local cmdline = "rrdtool graph " .. png - - for i, opt in ipairs(self.args) do - - opt = opt .. "" -- force string - - if rrd then - opt = opt:gsub( "{file}", rrd ) - end - - if opt:match("[^%w]") then - cmdline = cmdline .. " '" .. opt .. "'" - else - cmdline = cmdline .. " " .. opt - end - end - - -- execute rrdtool - local rrdtool = io.popen( cmdline ) - rrdtool:close() -end - -function Graph._generic( self, opts ) - - local images = { } - - -- remember images - table.insert( images, opts.image ) - - -- 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 - - -- 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 .. ":" .. 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 - end - - -- 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 numfmt = opts.number_format or "%6.1lf" - - local line_color - local area_color - - -- 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 - - -- 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 - - return images -end - -function Graph.render( self, host, plugin, plugin_instance ) - - dtype_instances = dtype_instances or { "" } - local pngs = { } - - -- check for a whole graph handler - local plugin_def = "luci.statistics.rrdtool.definitions." .. plugin - local stat, def = pcall( require, plugin_def ) - - if stat and def and type(def.rrdargs) == "function" then - 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 ) - - -- clear args - self:_clearargs() - end - end - else - - -- no graph handler, iterate over data types - for i, dtype in ipairs( self.tree:data_types( plugin, plugin_instance ) ) do - - -- check for data type handler - local dtype_def = plugin_def .. "." .. dtype - local stat, def = pcall( require, dtype_def ) - - if stat and def and type(def.rrdargs) == "function" then - 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 ) - - -- clear args - self:_clearargs() - end - end - else - - -- no data type handler, fall back to builtin definition - if type(self.defs.definitions[dtype]) == "table" then - - -- iterate over data type instances - for i, inst in ipairs( self.tree:data_instances( plugin, plugin_instance, dtype ) ) do - - local title = self:mktitle( host, plugin, plugin_instance, dtype, inst ) - local png = self:mkpngpath( host, plugin, plugin_instance, dtype, inst ) - local rrd = self:mkrrdpath( host, plugin, plugin_instance, dtype, inst ) - - self:_push( { "-t", title } ) - self:_push( self.defs.definitions[dtype] ) - - table.insert( pngs, png ) - - -- exec - self:_rrdtool( png, rrd ) - - -- clear args - self:_clearargs() - end - end - end - end - end - - return pngs -end - |