]> git.ipfire.org Git - collecty.git/blame - collecty/plugins/__init__.py
Documentation updates.
[collecty.git] / collecty / plugins / __init__.py
CommitLineData
a49a4b46
MT
1
2import os
3
4import rrdtool
5import time
6
7from threading import Thread
8
9import gettext
10_ = lambda x: gettext.ldgettext("collecty", x)
11
12registered_plugins = []
13
14def find(name):
15 for plugin in registered_plugins:
16 if plugin._type == name:
17 return plugin
18
19def register(plugin):
20 registered_plugins.append(plugin)
21
22class Plugin(Thread):
23 def __init__(self, collecty, **kwargs):
24 Thread.__init__(self)
25 self.collecty = collecty
26
27 self.interval = int(kwargs.get("interval", 60))
28
29 # Keepalive options
30 self.heartbeat = 2
31 self.killed = False
32
33 self.wakeup = self.interval / self.heartbeat
34
35 self.file = kwargs.get("file", None)
36 if not self.file.startswith("/"):
37 self.file = os.path.join("/var/rrd", self.file)
38
39 self.data = []
40
41 self.create()
42
43 def __repr__(self):
44 return "<Plugin %s>" % self._type
45
46 def __str__(self):
47 return "Plugin %s %s" % (self._type, self.file)
48
49 def run(self):
50 self.collecty.debug("%s started..." % self)
51
52 c = 0
53 while True:
54 if self.killed:
55 self.update()
56 self.collecty.debug("%s stoppped..." % self)
57 return
58
59 if c == 0:
60 self.data.append(self.collect())
61 self.collecty.debug("%s collectd: %s..." % (self, self.data[-1]))
62
63 self.update()
64
65 c = self.wakeup
66
67 c = c - 1
68 time.sleep(self.heartbeat)
69
70 def shutdown(self):
71 self.killed = True
72
73 def time(self):
74 return int(time.time()) # Should return time as int in UTC
75
76 def create(self):
77 if not os.path.exists(self.file):
78 rrdtool.create(self.file, *self._rrd)
79
80 def update(self):
81 if self.data:
82 self.collecty.debug("%s saving data..." % self)
83 rrdtool.update(self.file, *self.data)
84 self.data = []
85
86 def collect(self):
87 raise Exception, "Not implemented"
88
89 def graph(self, file, interval=None):
90 args = [ "--imgformat", "PNG",
91 "-w", "580", # Width of the graph
92 "-h", "240", # Height of the graph
93 "--interlaced", "--slope-mode", ]
94
95 intervals = { None : "-3h",
96 "hour" : "-1h",
97 "day" : "-25h",
98 "week" : "-360h" }
99
bffcb569 100 args.append("--start")
a49a4b46 101 if intervals.has_key(interval):
a49a4b46
MT
102 args.append(intervals[interval])
103 else:
a49a4b46
MT
104 args.append(interval)
105
106 info = { "file" : self.file }
107 for item in self._graph:
108 try:
109 args.append(item % info)
110 except TypeError:
111 args.append(item)
112
113 rrdtool.graph(file, *args)
114
115 def info(self):
116 return rrdtool.info(self.file)
117
118
119class PluginCpu(Plugin):
120 _name = "CPU Usage Plugin"
121 _type = "cpu"
122
123 _rrd = [ "DS:user:GAUGE:120:0:100",
124 "DS:nice:GAUGE:120:0:100",
125 "DS:sys:GAUGE:120:0:100",
126 "DS:idle:GAUGE:120:0:100",
127 "DS:wait:GAUGE:120:0:100",
128 "DS:interrupt:GAUGE:120:0:100",
129 "RRA:AVERAGE:0.5:1:2160",
130 "RRA:AVERAGE:0.5:5:2016",
131 "RRA:AVERAGE:0.5:15:2880",
132 "RRA:AVERAGE:0.5:60:8760" ]
133
134 _graph = [ "DEF:user=%(file)s:user:AVERAGE",
135 "DEF:nice=%(file)s:nice:AVERAGE",
136 "DEF:sys=%(file)s:sys:AVERAGE",
137 "DEF:idle=%(file)s:idle:AVERAGE",
138 "DEF:wait=%(file)s:wait:AVERAGE",
139 "DEF:interrupt=%(file)s:interrupt:AVERAGE",
140 "AREA:user#ff0000:%-15s" % _("User"),
141 "VDEF:usermin=user,MINIMUM",
142 "VDEF:usermax=user,MAXIMUM",
143 "VDEF:useravg=user,AVERAGE",
144 "GPRINT:usermax:%12s\:" % _("Maximum") + " %6.2lf" ,
145 "GPRINT:usermin:%12s\:" % _("Minimum") + " %6.2lf",
146 "GPRINT:useravg:%12s\:" % _("Average") + " %6.2lf\\n",
147 "STACK:nice#ff3300:%-15s" % _("Nice"),
148 "VDEF:nicemin=nice,MINIMUM",
149 "VDEF:nicemax=nice,MAXIMUM",
150 "VDEF:niceavg=nice,AVERAGE",
151 "GPRINT:nicemax:%12s\:" % _("Maximum") + " %6.2lf" ,
152 "GPRINT:nicemin:%12s\:" % _("Minimum") + " %6.2lf",
153 "GPRINT:niceavg:%12s\:" % _("Average") + " %6.2lf\\n",
154 "STACK:sys#ff6600:%-15s" % _("System"),
155 "VDEF:sysmin=sys,MINIMUM",
156 "VDEF:sysmax=sys,MAXIMUM",
157 "VDEF:sysavg=sys,AVERAGE",
158 "GPRINT:sysmax:%12s\:" % _("Maximum") + " %6.2lf" ,
159 "GPRINT:sysmin:%12s\:" % _("Minimum") + " %6.2lf",
160 "GPRINT:sysavg:%12s\:" % _("Average") + " %6.2lf\\n",
161 "STACK:wait#ff9900:%-15s" % _("Wait"),
162 "VDEF:waitmin=wait,MINIMUM",
163 "VDEF:waitmax=wait,MAXIMUM",
164 "VDEF:waitavg=wait,AVERAGE",
165 "GPRINT:waitmax:%12s\:" % _("Maximum") + " %6.2lf" ,
166 "GPRINT:waitmin:%12s\:" % _("Minimum") + " %6.2lf",
167 "GPRINT:waitavg:%12s\:" % _("Average") + " %6.2lf\\n",
168 "STACK:interrupt#ffcc00:%-15s" % _("Interrupt"),
169 "VDEF:interruptmin=interrupt,MINIMUM",
170 "VDEF:interruptmax=interrupt,MAXIMUM",
171 "VDEF:interruptavg=interrupt,AVERAGE",
172 "GPRINT:interruptmax:%12s\:" % _("Maximum") + " %6.2lf" ,
173 "GPRINT:interruptmin:%12s\:" % _("Minimum") + " %6.2lf",
174 "GPRINT:interruptavg:%12s\:" % _("Average") + " %6.2lf\\n",
175 "STACK:idle#ffff00:%-15s" % _("Idle"),
176 "VDEF:idlemin=idle,MINIMUM",
177 "VDEF:idlemax=idle,MAXIMUM",
178 "VDEF:idleavg=idle,AVERAGE",
179 "GPRINT:idlemax:%12s\:" % _("Maximum") + " %6.2lf" ,
180 "GPRINT:idlemin:%12s\:" % _("Minimum") + " %6.2lf",
181 "GPRINT:idleavg:%12s\:" % _("Average") + " %6.2lf\\n", ]
182
183 def __init__(self, collecty, **kwargs):
184 Plugin.__init__(self, collecty, **kwargs)
185
186 def collect(self):
187 ret = "%s" % self.time()
188 f = open("/proc/stat")
189 for line in f.readlines():
190 if not line.startswith("cpu"):
191 continue
192 a = line.split()
193 if len(a) < 6:
194 continue
195
196 user = float(a[1])
197 nice = float(a[2])
198 sys = float(a[3])
199 idle = float(a[4])
200 wait = float(a[5])
201 interrupt = float(a[6])
202 sum = float(user + nice + sys + idle + wait + interrupt)
203
204 ret += ":%s" % (user * 100 / sum)
205 ret += ":%s" % (nice * 100 / sum)
206 ret += ":%s" % (sys * 100 / sum)
207 ret += ":%s" % (idle * 100 / sum)
208 ret += ":%s" % (wait * 100 / sum)
209 ret += ":%s" % (interrupt * 100 / sum)
210 break
211
212 f.close()
213 return ret
214
215register(PluginCpu)
216
217
218class PluginLoad(Plugin):
219 _name = "Loadaverage Plugin"
220 _type = "load"
221
222 _rrd = ["DS:load1:GAUGE:120:0:U",
223 "DS:load5:GAUGE:120:0:U",
224 "DS:load15:GAUGE:120:0:U",
225 "RRA:AVERAGE:0.5:1:2160",
226 "RRA:AVERAGE:0.5:5:2016",
227 "RRA:AVERAGE:0.5:15:2880",
228 "RRA:AVERAGE:0.5:60:8760" ]
229
230 _graph = [ "DEF:load1=%(file)s:load1:AVERAGE",
231 "DEF:load5=%(file)s:load5:AVERAGE",
232 "DEF:load15=%(file)s:load15:AVERAGE",
233 "AREA:load1#ff0000:%s" % _("Load average 1m"),
234 "VDEF:load1min=load1,MINIMUM",
235 "VDEF:load1max=load1,MAXIMUM",
236 "VDEF:load1avg=load1,AVERAGE",
237 "GPRINT:load1max:%12s\:" % _("Maximum") + " %6.2lf" ,
238 "GPRINT:load1min:%12s\:" % _("Minimum") + " %6.2lf",
239 "GPRINT:load1avg:%12s\:" % _("Average") + " %6.2lf\\n",
240 "AREA:load5#ff9900:%s" % _("Load average 5m"),
241 "VDEF:load5min=load5,MINIMUM",
242 "VDEF:load5max=load5,MAXIMUM",
243 "VDEF:load5avg=load5,AVERAGE",
244 "GPRINT:load5max:%12s\:" % _("Maximum") + " %6.2lf" ,
245 "GPRINT:load5min:%12s\:" % _("Minimum") + " %6.2lf",
246 "GPRINT:load5avg:%12s\:" % _("Average") + " %6.2lf\\n",
247 "AREA:load15#ffff00:%s" % _("Load average 15m"),
248 "VDEF:load15min=load15,MINIMUM",
249 "VDEF:load15max=load15,MAXIMUM",
250 "VDEF:load15avg=load15,AVERAGE",
251 "GPRINT:load15max:%12s\:" % _("Maximum") + " %6.2lf" ,
252 "GPRINT:load15min:%12s\:" % _("Minimum") + " %6.2lf",
253 "GPRINT:load15avg:%12s\:" % _("Average") + " %6.2lf\\n",
254 "LINE:load5#dd8800",
255 "LINE:load1#dd0000", ]
256
257 def __init__(self, collecty, **kwargs):
258 Plugin.__init__(self, collecty, **kwargs)
259
260 def collect(self):
261 ret = "%s" % self.time()
262 for load in os.getloadavg():
263 ret += ":%s" % load
264 return ret
265
266register(PluginLoad)
267
268
269class PluginMem(Plugin):
270 _name = "Memory Usage Plugin"
271 _type = "mem"
272
273 _rrd = ["DS:used:GAUGE:120:0:100",
274 "DS:cached:GAUGE:120:0:100",
275 "DS:buffered:GAUGE:120:0:100",
276 "DS:free:GAUGE:120:0:100",
277 "DS:swap:GAUGE:120:0:100",
278 "RRA:AVERAGE:0.5:1:2160",
279 "RRA:AVERAGE:0.5:5:2016",
280 "RRA:AVERAGE:0.5:15:2880",
281 "RRA:AVERAGE:0.5:60:8760" ]
282
283 _graph = [ "DEF:used=%(file)s:used:AVERAGE",
284 "DEF:cached=%(file)s:cached:AVERAGE",
285 "DEF:buffered=%(file)s:buffered:AVERAGE",
286 "DEF:free=%(file)s:free:AVERAGE",
287 "DEF:swap=%(file)s:swap:AVERAGE",
288 "AREA:used#0000ee:%-15s" % _("Used memory"),
289 "VDEF:usedmin=used,MINIMUM",
290 "VDEF:usedmax=used,MAXIMUM",
291 "VDEF:usedavg=used,AVERAGE",
292 "GPRINT:usedmax:%12s\:" % _("Maximum") + " %6.2lf" ,
293 "GPRINT:usedmin:%12s\:" % _("Minimum") + " %6.2lf",
294 "GPRINT:usedavg:%12s\:" % _("Average") + " %6.2lf\\n",
295 "STACK:cached#0099ee:%-15s" % _("Cached data"),
296 "VDEF:cachedmin=cached,MINIMUM",
297 "VDEF:cachedmax=cached,MAXIMUM",
298 "VDEF:cachedavg=cached,AVERAGE",
299 "GPRINT:cachedmax:%12s\:" % _("Maximum") + " %6.2lf" ,
300 "GPRINT:cachedmin:%12s\:" % _("Minimum") + " %6.2lf",
301 "GPRINT:cachedavg:%12s\:" % _("Average") + " %6.2lf\\n",
302 "STACK:buffered#4499ff:%-15s" % _("Buffered data"),
303 "VDEF:bufferedmin=buffered,MINIMUM",
304 "VDEF:bufferedmax=buffered,MAXIMUM",
305 "VDEF:bufferedavg=buffered,AVERAGE",
306 "GPRINT:bufferedmax:%12s\:" % _("Maximum") + " %6.2lf" ,
307 "GPRINT:bufferedmin:%12s\:" % _("Minimum") + " %6.2lf",
308 "GPRINT:bufferedavg:%12s\:" % _("Average") + " %6.2lf\\n",
309 "STACK:free#7799ff:%-15s" % _("Free memory"),
310 "VDEF:freemin=free,MINIMUM",
311 "VDEF:freemax=free,MAXIMUM",
312 "VDEF:freeavg=free,AVERAGE",
313 "GPRINT:freemax:%12s\:" % _("Maximum") + " %6.2lf" ,
314 "GPRINT:freemin:%12s\:" % _("Minimum") + " %6.2lf",
315 "GPRINT:freeavg:%12s\:" % _("Average") + " %6.2lf\\n",
316 "LINE3:swap#ff0000:%-15s" % _("Used Swap space"),
317 "VDEF:swapmin=swap,MINIMUM",
318 "VDEF:swapmax=swap,MAXIMUM",
319 "VDEF:swapavg=swap,AVERAGE",
320 "GPRINT:swapmax:%12s\:" % _("Maximum") + " %6.2lf" ,
321 "GPRINT:swapmin:%12s\:" % _("Minimum") + " %6.2lf",
322 "GPRINT:swapavg:%12s\:" % _("Average") + " %6.2lf\\n", ]
323
324 def __init__(self, collecty, **kwargs):
325 Plugin.__init__(self, collecty, **kwargs)
326
327 def collect(self):
328 ret = "%s" % self.time()
329 f = open("/proc/meminfo")
330 for line in f.readlines():
331 if line.startswith("MemTotal:"):
332 total = float(line.split()[1])
333 if line.startswith("MemFree:"):
334 free = float(line.split()[1])
335 elif line.startswith("Buffers:"):
336 buffered = float(line.split()[1])
337 elif line.startswith("Cached:"):
338 cached = float(line.split()[1])
339 elif line.startswith("SwapTotal:"):
340 swapt = float(line.split()[1])
341 elif line.startswith("SwapFree:"):
342 swapf = float(line.split()[1])
343
344 f.close()
345
346 ret += ":%s" % ((total - (free + buffered + cached)) * 100 / total)
347 ret += ":%s" % (cached * 100 / total)
348 ret += ":%s" % (buffered * 100 / total)
349 ret += ":%s" % (free * 100 / total)
350 ret += ":%s" % ((swapt - swapf) * 100 / swapt)
351
352 return ret
353
354register(PluginMem)