Merge pull request #1188 from dibdot/master
[project/luci.git] / applications / luci-app-statistics / luasrc / statistics / datatree.lua
1 -- Copyright 2008 Freifunk Leipzig / Jo-Philipp Wich <jow@openwrt.org>
2 -- Licensed to the public under the Apache License 2.0.
3
4 module("luci.statistics.datatree", package.seeall)
5
6 local util = require("luci.util")
7 local sys = require("luci.sys")
8 local fs = require("nixio.fs")
9 local uci = require("luci.model.uci").cursor()
10 local sections = uci:get_all("luci_statistics")
11
12
13 Instance = util.class()
14
15 function Instance.__init__( self, host )
16 self._host = host or sys.hostname()
17 self._libdir = "/usr/lib/collectd"
18 self._rrddir = "/tmp/rrd"
19
20 if sections and sections.collectd then
21 self._host = host or sections.collectd.Hostname or sys.hostname()
22 self._libdir = sections.collectd.PluginDir or "/usr/lib/collectd"
23 end
24 if sections and sections.collectd_rrdtool then
25 self._rrddir = sections.collectd_rrdtool.DataDir or "/tmp/rrd"
26 end
27
28 self._libdir = self._libdir:gsub("/$","")
29 self._rrddir = self._rrddir:gsub("/$","")
30 self._plugins = { }
31
32 self:_scan()
33 end
34
35 function Instance._mkpath( self, plugin, pinstance )
36 local dir = self._rrddir .. "/" .. self._host
37
38 if type(plugin) == "string" and plugin:len() > 0 then
39 dir = dir .. "/" .. plugin
40
41 if type(pinstance) == "string" and pinstance:len() > 0 then
42 dir = dir .. "-" .. pinstance
43 end
44 end
45
46 return dir
47 end
48
49 function Instance._ls( self, ... )
50 local ditr = fs.dir(self:_mkpath(...))
51 if ditr then
52 local dirs = { }
53 while true do
54 local d = ditr()
55 if not d then break end
56 dirs[#dirs+1] = d
57 end
58 return dirs
59 end
60 end
61
62 function Instance._notzero( self, table )
63 for k in pairs(table) do
64 return true
65 end
66
67 return false
68 end
69
70 function Instance._scan( self )
71 local dirs = self:_ls()
72 if not dirs then
73 return
74 end
75
76 -- for i, plugin in ipairs( dirs ) do
77 -- if plugin:match("%w+.so") then
78 -- self._plugins[ plugin:gsub("%.so$", "") ] = { }
79 -- end
80 -- end
81
82 for _, dir in ipairs(dirs) do
83 if dir ~= "." and dir ~= ".." and
84 fs.stat(self:_mkpath(dir)).type == "dir"
85 then
86 local plugin = dir:gsub("%-.+$", "")
87 if not self._plugins[plugin] then
88 self._plugins[plugin] = { }
89 end
90 end
91 end
92
93 for plugin, instances in pairs( self._plugins ) do
94
95 local dirs = self:_ls()
96
97 if type(dirs) == "table" then
98 for i, dir in ipairs(dirs) do
99 if dir:find( plugin .. "%-" ) or dir == plugin then
100 local instance = ""
101
102 if dir ~= plugin then
103 instance = dir:gsub( plugin .. "%-", "", 1 )
104 end
105
106 instances[instance] = { }
107 end
108 end
109 end
110
111 for instance, data_instances in pairs( instances ) do
112
113 dirs = self:_ls(plugin, instance)
114
115 if type(dirs) == "table" then
116 for i, file in ipairs(dirs) do
117 if file:find("%.rrd") then
118 file = file:gsub("%.rrd","")
119
120 local data_type
121 local data_instance
122
123 if file:find("%-") then
124 data_type = file:gsub( "%-.+","" )
125 data_instance = file:gsub( "[^%-]-%-", "", 1 )
126 else
127 data_type = file
128 data_instance = ""
129 end
130
131 if not data_instances[data_type] then
132 data_instances[data_type] = { data_instance }
133 else
134 table.insert( data_instances[data_type], data_instance )
135 end
136 end
137 end
138 end
139 end
140 end
141 end
142
143
144 function Instance.plugins( self )
145 local rv = { }
146
147 for plugin, val in pairs( self._plugins ) do
148 if self:_notzero( val ) then
149 table.insert( rv, plugin )
150 end
151 end
152
153 return rv
154 end
155
156 function Instance.plugin_instances( self, plugin )
157 local rv = { }
158
159 for instance, val in pairs( self._plugins[plugin] ) do
160 table.insert( rv, instance )
161 end
162
163 return rv
164 end
165
166 function Instance.data_types( self, plugin, instance )
167 local rv = { }
168 local p = self._plugins[plugin]
169
170 if type(p) == "table" and type(p[instance]) == "table" then
171 for type, val in pairs(p[instance]) do
172 table.insert( rv, type )
173 end
174 end
175
176 return rv
177 end
178
179 function Instance.data_instances( self, plugin, instance, dtype )
180 local rv = { }
181 local p = self._plugins[plugin]
182
183 if type(p) == "table" and type(p[instance]) == "table" and type(p[instance][dtype]) == "table" then
184 for i, instance in ipairs(p[instance][dtype]) do
185 table.insert( rv, instance )
186 end
187 end
188
189 return rv
190 end
191
192 function Instance.host_instances( self )
193 local hosts_path = fs.glob(self._rrddir..'/*')
194 local hosts = { }
195
196 if hosts_path then
197 local path
198 for path in hosts_path do
199 hosts[#hosts+1] = fs.basename(path)
200 end
201 end
202
203 return hosts
204 end
205