Added compact data retrieval method to avoid unnecessary data transmission/plotting.
[smonitor.git] / monitor / http_display.py
blob78c2f151e9c203db7445aa815ae1f9b0b0c6b072
1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*-
4 # Server monitoring system
6 # Copyright © 2011 Rodrigo Eduardo Lazo Paz
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 """Http/html Exporter module.
25 Based on CherryPy framework, this module exposes the collected data
26 through HTTP. Data is formatted in html, which is generated based on a
27 very simple template system, based on Python's `string.Template`
28 functionality. Refer to each method of `MonitorHttpHandler` decorated
29 with `@cherry.expose` for the name of the template file used an the
30 list of variables available.
32 The intended entry point for this module is the `main` function, which
33 instantiates and configures the HTTP server. For further details,
34 refer to its docstring.
35 """
37 __author__ = "rlazo.paz@gmail.com (Rodrigo Lazo)"
38 __version__ = 0.2
40 from datetime import datetime
42 import cherrypy
43 from cherrypy.lib.static import serve_fileobj
44 from jinja2 import Environment, PackageLoader
46 from datastore import DataStore, DataEntry, DataPoint # pylint: disable=W0611
47 from datetime import datetime
48 from extra import plotting
50 def timestampformat(value, format_str='%H:%M:%S'):
51 return datetime.fromtimestamp(value).strftime(format_str)
53 # TODO: (09/19) add support for custom made plots based on GET request
54 # params, providing an on-line plotting tool.
55 # TODO: (09/19) evaluate alternatives to error messages, perhaps 404?
56 # TODO: (09/19) add more variables to the templates
57 class MonitorHttpHandler(object):
58 """Custom HTTP handler class."""
59 def __init__(self, store, templates_path, static_path):
60 self._store = store
61 self._templates_path = templates_path
62 self._static_path = static_path
63 self.env = Environment(loader=PackageLoader('monitor', 'www_templates'))
64 self.env.filters["timestampformat"] = timestampformat
66 @cherrypy.expose
67 def index(self):
68 """Web system root url ('/').
70 Template: index.html
71 Vars: title, timestamp, body.
72 """
73 template = self.env.get_template('index.html')
74 references= self._get_default_references()
75 references.update({"title": "Monitoring",
76 "body": "<h1>seee</h1>"})
77 return template.render(references)
79 @cherrypy.expose
80 def vars(self):
81 """Displays a list of collected vars.
83 Each item in the list links to a page (`var?name=varname`)
84 which displays more detailed information.
86 Template: simple.html
87 Vars: title, timestamp, body.
88 """
89 template = self.env.get_template('vars.html')
90 references = self._get_default_references()
91 references.update({"title": "List of monitored vars",
92 "vars" : self._store.list_vars()})
93 return template.render(references)
95 @cherrypy.expose
96 def hosts(self):
97 """Displays a list of monitored hosts.
99 Each item in the list links to a page (`host?name=hostname`)
100 which displays more detailed information.
102 Template: simple.html
103 Vars: title, timestamp, body.
105 template = self.env.get_template('hosts.html')
106 references = self._get_default_references()
107 references.update({"title": "List of monitored vars",
108 "vars" : self._store.list_groups()})
109 return template.render(references)
111 @cherrypy.expose
112 def var(self, name):
113 """Displays information about a single variable.
115 Shows a consolidated plotting of collected data by hosts.
117 Args:
118 - `name`: String, variable to display
120 Template: simple.html
121 Vars: title, timestamp, body.
123 template = self.env.get_template('var.html')
124 references = self._get_default_references()
125 references["title"] = "Historic Values of var: %s" % name
126 data = self._store.get_var(name)
127 if data:
128 # filename, _ = plotting.new_multigraph(data, name, self._static_path)
129 filename, _ = plotting.gnuplot_new_multigraph(data, name, self._static_path)
130 references["filename"] = filename
131 references["items"] = [{'hostname' : k, 'value': v.get_latest()} for k, v in data.iteritems()]
132 return template.render(references)
134 def host(self, name):
135 """Displays information about a single host.
137 Shows a series of plots displaying each collected variable
138 individually.
140 Args:
141 - `name`: String, host to display.
143 Template: simple.html
144 Vars: title, timestamp, body.
146 template = self.env.get_template('host.html')
147 references = self._get_default_references()
148 references["title"] = "Historic Values of host: %s" % name
149 data = self._store.get_group(name)
150 if data:
151 items = []
152 for k, entry in data.iteritems():
153 values = entry.get_all()
154 tuples = [x.as_tuple() for x in values]
156 # filename, _ = plotting.new_graph(tuples, k, self._static_path)
157 filename, _ = plotting.gnuplot_new_graph(tuples, k, self._static_path)
158 items.append({'file': filename, 'value': values[-1]})
159 references["items"] = items
160 return template.render(references)
162 @cherrypy.expose
163 def host(self, name):
164 """Displays information about a single host.
166 Shows a series of plots displaying each collected variable
167 individually.
169 Args:
170 - `name`: String, host to display.
172 Template: simple.html
173 Vars: title, timestamp, body.
175 template = self.env.get_template('host.html')
176 references = self._get_default_references()
177 references["title"] = "Historic Values of host: %s" % name
178 references["data"] = self._store.get_group(name).items()
179 return template.render(references)
181 @cherrypy.expose
182 def snapshot(self):
183 """Returns a snapshot of the state of the database."""
184 filename = "snapshot-%s.pickle" % \
185 datetime.strftime(datetime.now(), "%d%m%y-%H%M")
186 return serve_fileobj(self._store.dump_obj(),
187 disposition="attachment",
188 content_type="application/octet-stream",
189 name=filename)
191 def _get_default_references(self):
192 """Returns a dic with basic references already set.
194 Includes:
195 - timestamp (current timestamp).
196 - is_snapshot (if current data store is a snapshot)
198 return {"timestamp": str(datetime.now()),
199 "is_snapshot": self._store.is_snapshot()}
203 def main(store, port, templates_path, static_path):
204 """HTTP server starter.
206 This is a blocking function.
208 Arguments:
209 - `store`: DataStore, where to extract the data.
210 - `port`: Integer, server port.
211 - `templates_path`: String, fullpath of the templates directory
212 - `static_path`: String, fullpath of directory for generated static files
214 conf = {"global": {'server.socket_port': port},
215 "/static": {'tools.staticdir.on': True,
216 'tools.staticdir.dir': static_path}}
218 cherrypy.quickstart(MonitorHttpHandler(store, templates_path, static_path),
219 config=conf)