Use luci.fs.access instead of luci.fs.isfile where applicable
[project/luci.git] / applications / luci-statistics / luasrc / controller / luci_statistics / luci_statistics.lua
1 --[[
2
3 Luci statistics - statistics controller module
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.controller.luci_statistics.luci_statistics", package.seeall)
17
18 function index()
19
20         require("luci.fs")
21         require("luci.util")
22         require("luci.i18n")
23         require("luci.statistics.datatree")
24
25         -- load language files
26         luci.i18n.loadc("rrdtool")
27         luci.i18n.loadc("statistics")
28
29         -- get rrd data tree
30         local tree = luci.statistics.datatree.Instance()
31
32         -- override entry(): check for existance <plugin>.so where <plugin> is derived from the called path
33         function _entry( path, ... )
34                 local file = path[5] or path[4]
35                 if luci.fs.access( "/usr/lib/collectd/" .. file .. ".so" ) then
36                         entry( path, ... )
37                 end
38         end
39
40         -- override i18n(): try to translate stat_<str> or fall back to <str>
41         function _i18n( str )
42                 return luci.i18n.translate( "stat_" .. str, str )
43         end
44
45         -- our collectd menu
46         local collectd_menu = {
47                 output  = { "rrdtool", "network", "unixsock", "csv" },
48                 system  = { "exec", "email", "cpu", "df", "disk", "irq", "processes", "load" },
49                 network = { "interface", "netlink", "iptables", "tcpconns", "ping", "dns", "wireless" }
50         }
51
52         -- create toplevel menu nodes
53         local st = entry({"admin", "statistics"},             call("statistics_index"),        _i18n("statistics"), 80)
54         st.i18n = "statistics"
55         st.index = true
56         
57         entry({"admin", "statistics", "collectd"}, cbi("luci_statistics/collectd"), _i18n("collectd"),   10).subindex = true
58         
59
60         -- populate collectd plugin menu
61         local index = 1
62         for section, plugins in luci.util.kspairs( collectd_menu ) do
63                 entry(
64                         { "admin", "statistics", "collectd", section },
65                         call( "statistics_" .. section .. "plugins" ),
66                         _i18n( section .. "plugins" ),
67                         index * 10
68                 ).index = true
69
70                 for j, plugin in luci.util.vspairs( plugins ) do
71                         _entry(
72                                 { "admin", "statistics", "collectd", section, plugin },
73                                 cbi("luci_statistics/" .. plugin ),
74                                 _i18n( plugin ),
75                                 j * 10
76                         )
77                 end
78
79                 index = index + 1
80         end
81
82         -- output views
83         local page = entry( { "admin", "statistics", "graph" }, call("statistics_index"), _i18n("graphs"), 80)
84               page.i18n     = "statistics"
85               page.setuser  = "nobody"
86               page.setgroup = "nogroup"
87
88         local vars = luci.http.formvalue(nil, true)
89         local span = vars.timespan or nil
90
91         for i, plugin in luci.util.vspairs( tree:plugins() ) do
92
93                 -- get plugin instances
94                 local instances = tree:plugin_instances( plugin )
95
96                 -- plugin menu entry
97                 entry(
98                         { "admin", "statistics", "graph", plugin },
99                         call("statistics_render"), _i18n( plugin ), i
100                 ).query = { timespan = span }
101
102                 -- if more then one instance is found then generate submenu
103                 if #instances > 1 then
104                         for j, inst in luci.util.vspairs(instances) do
105                                 -- instance menu entry
106                                 entry(
107                                         { "admin", "statistics", "graph", plugin, inst },
108                                         call("statistics_render"), inst, j
109                                 ).query = { timespan = span }
110                         end
111                 end
112         end
113 end
114
115 function statistics_index()
116         luci.template.render("admin_statistics/index")
117 end
118
119 function statistics_outputplugins()
120         local plugins = { }
121
122         for i, p in ipairs({ "rrdtool", "network", "unixsock", "csv" }) do
123                 plugins[p] = luci.i18n.translate( "stat_" .. p, p )
124         end
125
126         luci.template.render("admin_statistics/outputplugins", {plugins=plugins})
127 end
128
129 function statistics_systemplugins()
130         local plugins = { }
131
132         for i, p in ipairs({ "exec", "email", "df", "disk", "irq", "processes", "cpu" }) do
133                 plugins[p] = luci.i18n.translate( "stat_" .. p, p )
134         end
135
136         luci.template.render("admin_statistics/systemplugins", {plugins=plugins})
137 end
138
139 function statistics_networkplugins()
140         local plugins = { }
141
142         for i, p in ipairs({ "interface", "netlink", "iptables", "tcpconns", "ping", "dns", "wireless" }) do
143                 plugins[p] = luci.i18n.translate( "stat_" .. p, p )
144         end
145
146         luci.template.render("admin_statistics/networkplugins", {plugins=plugins})
147 end
148
149
150 function statistics_render()
151
152         require("luci.statistics.rrdtool")
153         require("luci.template")
154         require("luci.model.uci")
155
156         local vars  = luci.http.formvalue()
157         local req   = luci.dispatcher.context.request
158         local path  = luci.dispatcher.context.path
159         local uci   = luci.model.uci.cursor()
160         local spans = luci.util.split( uci:get( "luci_statistics", "collectd_rrdtool", "RRATimespans" ), "%s+", nil, true )
161         local span  = vars.timespan or uci:get( "luci_statistics", "rrdtool", "default_timespan" ) or spans[1]
162         local graph = luci.statistics.rrdtool.Graph( luci.util.parse_units( span ) )
163
164         local plugin, instances
165         local images = { }
166
167         -- find requested plugin and instance
168         for i, p in ipairs( luci.dispatcher.context.path ) do
169                 if luci.dispatcher.context.path[i] == "graph" then
170                         plugin    = luci.dispatcher.context.path[i+1]
171                         instances = { luci.dispatcher.context.path[i+2] }
172                 end
173         end
174
175         -- no instance requested, find all instances
176         if #instances == 0 then
177                 instances = { graph.tree:plugin_instances( plugin )[1] }
178
179         -- index instance requested
180         elseif instances[1] == "-" then
181                 instances[1] = ""
182         end
183
184
185         -- render graphs
186         for i, inst in ipairs( instances ) do
187                 for i, img in ipairs( graph:render( plugin, inst ) ) do
188                         table.insert( images, graph:strippngpath( img ) )
189                 end
190         end
191
192         luci.template.render( "public_statistics/graph", {
193                 images           = images,
194                 plugin           = plugin,
195                 timespans        = spans,
196                 current_timespan = span
197         } )
198 end