]>
git.ipfire.org Git - collecty.git/blob - collecty/plugins/base.py
2 ###############################################################################
4 # collecty - A system statistics collection daemon for IPFire #
5 # Copyright (C) 2012 IPFire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
28 from ..constants
import *
32 def __init__(self
, timeout
, heartbeat
=1):
33 self
.timeout
= timeout
34 self
.heartbeat
= heartbeat
40 self
.start
= time
.time()
42 # Has this timer been killed?
47 return time
.time() - self
.start
53 while self
.elapsed
< self
.timeout
and not self
.killed
:
54 time
.sleep(self
.heartbeat
)
56 return self
.elapsed
> self
.timeout
59 class Plugin(threading
.Thread
):
60 # The name of this plugin.
63 # A description for this plugin.
66 # The schema of the RRD database.
69 # Instructions how to create the graph.
72 # Extra arguments passed to rrdgraph.
75 # The default interval of this plugin.
78 def __init__(self
, collecty
, **kwargs
):
79 threading
.Thread
.__init
__(self
, name
=self
.description
)
82 self
.collecty
= collecty
84 # Check if this plugin was configured correctly.
85 assert self
.name
, "Name of the plugin is not set: %s" % self
.name
86 assert self
.description
, "Description of the plugin is not set: %s" % self
.description
87 assert self
.rrd_schema
89 # Initialize the logger.
90 self
.log
= logging
.getLogger("collecty.plugins.%s" % self
.name
)
91 self
.log
.propagate
= 1
95 # Run some custom initialization.
98 # Create the database file.
103 self
.timer
= Timer(self
.interval
)
105 self
.log
.info(_("Successfully initialized (%s).") % self
.id)
108 return "<Plugin %s>" % self
.name
111 return "Plugin %s %s" % (self
.name
, self
.file)
116 A unique ID of the plugin instance.
123 Returns the interval in milliseconds, when the read method
124 should be called again.
126 # XXX read this from the settings
128 # Otherwise return the default.
129 return self
.default_interval
134 The absolute path to the RRD file of this plugin.
136 return os
.path
.join(DATABASE_DIR
, "%s.rrd" % self
.id)
140 Creates an empty RRD file with the desired data structures.
142 # Skip if the file does already exist.
143 if os
.path
.exists(self
.file):
146 dirname
= os
.path
.dirname(self
.file)
147 if not os
.path
.exists(dirname
):
150 rrdtool
.create(self
.file, *self
.rrd_schema
)
152 self
.log
.debug(_("Created RRD file %s.") % self
.file)
155 return rrdtool
.info(self
.file)
159 def init(self
, **kwargs
):
161 Do some custom initialization stuff here.
167 Gathers the statistical data, this plugin collects.
169 raise NotImplementedError
173 Flushes the read data to disk.
175 # Do nothing in case there is no data to submit.
179 self
.log
.debug(_("Submitting data to database. %d entries.") % len(self
.data
))
180 rrdtool
.update(self
.file, *self
.data
)
183 def _read(self
, *args
, **kwargs
):
185 This method catches errors from the read() method and logs them.
188 return self
.read(*args
, **kwargs
)
190 # Catch any exceptions, so collecty does not crash.
192 self
.log
.critical(_("Unhandled exception in read()!"), exc_info
=True)
194 def _submit(self
, *args
, **kwargs
):
196 This method catches errors from the submit() method and logs them.
199 return self
.submit(*args
, **kwargs
)
201 # Catch any exceptions, so collecty does not crash.
203 self
.log
.critical(_("Unhandled exception in submit()!"), exc_info
=True)
206 self
.log
.debug(_("Started."))
212 # Wait until the timer has successfully elapsed.
213 if self
.timer
.wait():
214 self
.log
.debug(_("Collecting..."))
218 self
.log
.debug(_("Stopped."))
221 self
.log
.debug(_("Received shutdown signal."))
224 # Kill any running timers.
231 Returns the current timestamp in the UNIX timestamp format (UTC).
233 return int(time
.time())
235 def graph(self
, file, interval
=None,
236 width
=GRAPH_DEFAULT_WIDTH
, height
=GRAPH_DEFAULT_HEIGHT
):
239 "--width", "%d" % width
,
240 "--height", "%d" % height
,
242 args
+= self
.collecty
.graph_default_arguments
243 args
+= self
.rrd_graph_args
253 args
.append("--start")
254 if intervals
.has_key(interval
):
255 args
.append(intervals
[interval
])
257 args
.append(interval
)
259 info
= { "file" : self
.file }
260 for item
in self
.rrd_graph
:
262 args
.append(item
% info
)
266 rrdtool
.graph(file, *args
)