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