03608b10bbad467cfb6025850ae9a31616b6bc7c
[project/luci.git] / applications / luci-statistics / luasrc / statistics / datatree.lua
1 --[[
2
3 Luci statistics - rrd data tree builder
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13
14 ]]--
15
16 module("luci.statistics.datatree", package.seeall)
17
18 local util = require("luci.util")
19 local sys  = require("luci.sys")
20 local fs   = require("luci.fs")
21 local uci  = require("luci.model.uci").Session()
22 local sections = uci:sections( "luci_statistics" )
23
24
25 Instance = util.class()
26
27 function Instance.__init__( self, host )
28         self._host    = host or sections.collectd.Hostname or sys.hostname()
29         self._libdir  = sections.collectd.PluginDir        or "/usr/lib/collectd"
30         self._rrddir  = sections.collectd_rrdtool.DataDir  or "/tmp/rrd"
31
32         self._libdir  = self._libdir:gsub("/$","")
33         self._rrddir  = self._rrddir:gsub("/$","")
34         self._plugins = { }
35
36         self:_scan()
37 end
38
39 function Instance._mkpath( self, plugin, pinstance )
40         local dir = self._rrddir .. "/" .. self._host
41
42         if type(plugin) == "string" and plugin:len() > 0 then
43                 dir = dir .. "/" .. plugin
44
45                 if type(pinstance) == "string" and pinstance:len() > 0 then
46                         dir = dir .. "-" .. pinstance
47                 end
48         end
49
50         return dir
51 end
52
53 function Instance._notzero( self, table )
54         for k in pairs(table) do
55                 return true
56         end
57
58         return false
59 end
60
61 function Instance._scan( self )
62         local dir = fs.dir( self._libdir )
63         if not dir then
64                 return
65         end
66         for i, plugin in ipairs( dir ) do
67                 if plugin:match("%w+.so") then
68                         self._plugins[ plugin:gsub(".so", "") ] = { }
69                 end
70         end
71
72         for plugin, instances in pairs( self._plugins ) do
73
74                 local dirs = fs.dir( self:_mkpath() )
75
76                 if type(dirs) == "table" then
77                         for i, dir in ipairs(dirs) do
78                                 if dir:find( plugin .. "%-" ) or dir == plugin then
79                                         local instance = ""
80
81                                         if dir ~= plugin then
82                                                 instance = dir:gsub( plugin .. "%-", "", 1 )
83                                         end
84
85                                         instances[instance] = { }
86                                 end
87                         end
88                 end
89
90                 for instance, data_instances in pairs( instances ) do
91
92                         dirs = fs.dir( self:_mkpath( plugin, instance ) )
93
94                         if type(dirs) == "table" then
95                                 for i, file in ipairs(dirs) do
96                                         if file:find("%.rrd") then
97                                                 file = file:gsub("%.rrd","")
98
99                                                 local data_type
100                                                 local data_instance
101
102                                                 if file:find("%-") then
103                                                         data_type     = file:gsub( "%-.+","" )
104                                                         data_instance = file:gsub( "[^%-]-%-", "", 1 )
105                                                 else
106                                                         data_type     = file
107                                                         data_instance = ""
108                                                 end
109
110                                                 if not data_instances[data_type] then
111                                                         data_instances[data_type] = { data_instance }
112                                                 else
113                                                         table.insert( data_instances[data_type], data_instance )
114                                                 end
115                                         end
116                                 end
117                         end
118                 end
119         end
120 end
121
122
123 function Instance.plugins( self )
124         local rv = { }
125
126         for plugin, val in pairs( self._plugins ) do
127                 if self:_notzero( val ) then
128                         table.insert( rv, plugin )
129                 end
130         end
131
132         return rv
133 end
134
135 function Instance.plugin_instances( self, plugin )
136         local rv = { }
137
138         for instance, val in pairs( self._plugins[plugin] ) do
139                 table.insert( rv, instance )
140         end
141
142         return rv
143 end
144
145 function Instance.data_types( self, plugin, instance )
146         local rv = { }
147         local p  = self._plugins[plugin]
148
149         if type(p) == "table" and type(p[instance]) == "table" then
150                 for type, val in pairs(p[instance]) do
151                         table.insert( rv, type )
152                 end
153         end
154
155         return rv
156 end
157
158 function Instance.data_instances( self, plugin, instance, dtype )
159         local rv = { }
160         local p  = self._plugins[plugin]
161
162         if type(p) == "table" and type(p[instance]) == "table" and type(p[instance][dtype]) == "table" then
163                 for i, instance in ipairs(p[instance][dtype]) do
164                         table.insert( rv, instance )
165                 end
166         end
167
168         return rv
169 end