b494dc10843fc437eba88ef686168226e9ceb5c1
[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("nixio.fs")
21 local uci = require("luci.model.uci").cursor()
22 local sections = uci:get_all("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._ls( self, ... )
54 local ditr = fs.dir(self:_mkpath(...))
55 if ditr then
56 local dirs = { }
57 while true do
58 local d = ditr()
59 if not d then break end
60 dirs[#dirs+1] = d
61 end
62 return dirs
63 end
64 end
65
66 function Instance._notzero( self, table )
67 for k in pairs(table) do
68 return true
69 end
70
71 return false
72 end
73
74 function Instance._scan( self )
75 local dirs = self:_ls()
76 if not dirs then
77 return
78 end
79
80 -- for i, plugin in ipairs( dirs ) do
81 -- if plugin:match("%w+.so") then
82 -- self._plugins[ plugin:gsub("%.so$", "") ] = { }
83 -- end
84 -- end
85
86 for _, dir in ipairs(dirs) do
87 if dir ~= "." and dir ~= ".." and
88 fs.stat(self:_mkpath(dir)).type == "dir"
89 then
90 local plugin = dir:gsub("%-.+$", "")
91 if not self._plugins[plugin] then
92 self._plugins[plugin] = { }
93 end
94 end
95 end
96
97 for plugin, instances in pairs( self._plugins ) do
98
99 local dirs = self:_ls()
100
101 if type(dirs) == "table" then
102 for i, dir in ipairs(dirs) do
103 if dir:find( plugin .. "%-" ) or dir == plugin then
104 local instance = ""
105
106 if dir ~= plugin then
107 instance = dir:gsub( plugin .. "%-", "", 1 )
108 end
109
110 instances[instance] = { }
111 end
112 end
113 end
114
115 for instance, data_instances in pairs( instances ) do
116
117 dirs = self:_ls(plugin, instance)
118
119 if type(dirs) == "table" then
120 for i, file in ipairs(dirs) do
121 if file:find("%.rrd") then
122 file = file:gsub("%.rrd","")
123
124 local data_type
125 local data_instance
126
127 if file:find("%-") then
128 data_type = file:gsub( "%-.+","" )
129 data_instance = file:gsub( "[^%-]-%-", "", 1 )
130 else
131 data_type = file
132 data_instance = ""
133 end
134
135 if not data_instances[data_type] then
136 data_instances[data_type] = { data_instance }
137 else
138 table.insert( data_instances[data_type], data_instance )
139 end
140 end
141 end
142 end
143 end
144 end
145 end
146
147
148 function Instance.plugins( self )
149 local rv = { }
150
151 for plugin, val in pairs( self._plugins ) do
152 if self:_notzero( val ) then
153 table.insert( rv, plugin )
154 end
155 end
156
157 return rv
158 end
159
160 function Instance.plugin_instances( self, plugin )
161 local rv = { }
162
163 for instance, val in pairs( self._plugins[plugin] ) do
164 table.insert( rv, instance )
165 end
166
167 return rv
168 end
169
170 function Instance.data_types( self, plugin, instance )
171 local rv = { }
172 local p = self._plugins[plugin]
173
174 if type(p) == "table" and type(p[instance]) == "table" then
175 for type, val in pairs(p[instance]) do
176 table.insert( rv, type )
177 end
178 end
179
180 return rv
181 end
182
183 function Instance.data_instances( self, plugin, instance, dtype )
184 local rv = { }
185 local p = self._plugins[plugin]
186
187 if type(p) == "table" and type(p[instance]) == "table" and type(p[instance][dtype]) == "table" then
188 for i, instance in ipairs(p[instance][dtype]) do
189 table.insert( rv, instance )
190 end
191 end
192
193 return rv
194 end