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.
37 __author__
= "rlazo.paz@gmail.com (Rodrigo Lazo)"
40 from datetime
import datetime
43 from cherrypy
.lib
.static
import serve_fileobj
44 from jinja2
import Environment
, PackageLoader
46 from datastore
import DataStore
, DataEntry
, DataPoint
# pylint: disable=W0611
48 def timestampformat(value
, format_str
='%H:%M:%S'):
49 return datetime
.fromtimestamp(value
).strftime(format_str
)
51 # TODO: (09/19) add support for custom made plots based on GET request
52 # params, providing an on-line plotting tool.
53 # TODO: (09/19) evaluate alternatives to error messages, perhaps 404?
54 # TODO: (09/19) add more variables to the templates
55 class MonitorHttpHandler(object):
56 """Custom HTTP handler class."""
57 def __init__(self
, store
, templates_path
):
59 self
._templates
_path
= templates_path
60 self
.env
= Environment(loader
=PackageLoader('monitor', 'www_templates'))
61 self
.env
.filters
["timestampformat"] = timestampformat
65 """Web system root url ('/').
68 Vars: title, timestamp, body.
70 template
= self
.env
.get_template('index.html')
71 references
= self
._get
_default
_references
()
72 references
.update({"title": "Monitoring",
73 "body": "<h1>seee</h1>"})
74 return template
.render(references
)
78 """Displays a list of collected vars.
80 Each item in the list links to a page (`var?name=varname`)
81 which displays more detailed information.
84 Vars: title, timestamp, body.
86 template
= self
.env
.get_template('vars.html')
87 references
= self
._get
_default
_references
()
88 references
.update({"title": "List of monitored vars",
89 "vars" : self
._store
.list_vars()})
90 return template
.render(references
)
94 """Displays a list of monitored hosts.
96 Each item in the list links to a page (`host?name=hostname`)
97 which displays more detailed information.
100 Vars: title, timestamp, body.
102 template
= self
.env
.get_template('hosts.html')
103 references
= self
._get
_default
_references
()
104 references
.update({"title": "List of monitored vars",
105 "vars" : self
._store
.list_groups()})
106 return template
.render(references
)
110 """Displays information about a single variable.
112 Shows a consolidated plotting of collected data by hosts.
115 - `name`: String, variable to display
117 Template: simple.html
118 Vars: title, timestamp, body.
120 template
= self
.env
.get_template('var.html')
121 references
= self
._get
_default
_references
()
122 references
["title"] = "Historic Values of var: %s" % name
123 references
["data"] = self
._store
.get_var(name
)
125 for value
in references
["data"].itervalues():
126 value_range
.update([x
.value
for x
in value
.get_all_compact()])
127 if len(value_range
) > 1:
130 references
["single_value"] = value_range
.pop()
132 miny
= min([min(a
.get_all(), lambda x
: x
.value
)
133 for a
in references
["data"].values()])
134 maxy
= max([max(a
.get_all(), lambda x
: x
.value
)[1]
135 for a
in references
["data"].values()])
137 return template
.render(references
)
140 def host(self
, name
):
141 """Displays information about a single host.
143 Shows a series of plots displaying each collected variable
147 - `name`: String, host to display.
149 Template: simple.html
150 Vars: title, timestamp, body.
152 template
= self
.env
.get_template('host.html')
153 references
= self
._get
_default
_references
()
154 references
["title"] = "Historic Values of host: %s" % name
155 references
["data"] = self
._store
.get_group(name
).items()
156 return template
.render(references
)
160 """Returns a snapshot of the state of the database."""
161 filename
= "snapshot-%s.pickle" % \
162 datetime
.strftime(datetime
.now(), "%d%m%y-%H%M")
163 return serve_fileobj(self
._store
.dump_obj(),
164 disposition
="attachment",
165 content_type
="application/octet-stream",
168 def _get_default_references(self
):
169 """Returns a dic with basic references already set.
172 - timestamp (current timestamp).
173 - is_snapshot (if current data store is a snapshot)
175 return {"timestamp": str(datetime
.now()),
176 "is_snapshot": self
._store
.is_snapshot()}
180 def main(store
, port
, templates_path
):
181 """HTTP server starter.
183 This is a blocking function.
186 - `store`: DataStore, where to extract the data.
187 - `port`: Integer, server port.
188 - `templates_path`: String, fullpath of the templates directory
190 conf
= {"global": {'server.socket_port': port
}}
192 cherrypy
.quickstart(MonitorHttpHandler(store
, templates_path
),