]>
Commit | Line | Data |
---|---|---|
1 | #!/usr/bin/python3 | |
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 | ############################################################################### | |
21 | ||
22 | import multiprocessing | |
23 | ||
24 | from . import base | |
25 | ||
26 | from ..colours import * | |
27 | from ..constants import * | |
28 | from ..i18n import _ | |
29 | ||
30 | class GraphTemplateProcessor(base.GraphTemplate): | |
31 | name = "processor" | |
32 | ||
33 | @property | |
34 | def rrd_graph(self): | |
35 | return [ | |
36 | # Add all used CPU cycles | |
37 | "CDEF:usage=user,nice,+,sys,+,wait,+,irq,+,sirq,+,steal,+,guest,+,guest_nice,+", | |
38 | ||
39 | # Add idle to get the total number of cycles | |
40 | "CDEF:total=usage,idle,+", | |
41 | ||
42 | # Headline | |
43 | "COMMENT:%s" % EMPTY_LABEL, | |
44 | "COMMENT:%s" % (COLUMN % _("Current")), | |
45 | "COMMENT:%s" % (COLUMN % _("Average")), | |
46 | "COMMENT:%s" % (COLUMN % _("Minimum")), | |
47 | "COMMENT:%s\\j" % (COLUMN % _("Maximum")), | |
48 | ||
49 | "CDEF:usage_p=100,usage,*,total,/", | |
50 | "COMMENT: %s" % (LABEL % _("Total")), | |
51 | "GPRINT:usage_p_cur:%s" % PERCENTAGE, | |
52 | "GPRINT:usage_p_avg:%s" % PERCENTAGE, | |
53 | "GPRINT:usage_p_min:%s" % PERCENTAGE, | |
54 | "GPRINT:usage_p_max:%s\\j" % PERCENTAGE, | |
55 | ||
56 | EMPTY_LINE, | |
57 | ||
58 | "CDEF:user_p=100,user,*,total,/", | |
59 | "AREA:user_p%s:%s" % ( | |
60 | transparency(CPU_USER, AREA_OPACITY), | |
61 | LABEL % _("User"), | |
62 | ), | |
63 | "GPRINT:user_p_cur:%s" % PERCENTAGE, | |
64 | "GPRINT:user_p_avg:%s" % PERCENTAGE, | |
65 | "GPRINT:user_p_min:%s" % PERCENTAGE, | |
66 | "GPRINT:user_p_max:%s\\j" % PERCENTAGE, | |
67 | ||
68 | "CDEF:nice_p=100,nice,*,total,/", | |
69 | "AREA:nice_p%s:%s:STACK" % ( | |
70 | transparency(CPU_NICE, AREA_OPACITY), | |
71 | LABEL % _("Nice"), | |
72 | ), | |
73 | "GPRINT:nice_p_cur:%s" % PERCENTAGE, | |
74 | "GPRINT:nice_p_avg:%s" % PERCENTAGE, | |
75 | "GPRINT:nice_p_min:%s" % PERCENTAGE, | |
76 | "GPRINT:nice_p_max:%s\\j" % PERCENTAGE, | |
77 | ||
78 | "CDEF:sys_p=100,sys,*,total,/", | |
79 | "AREA:sys_p%s:%s:STACK" % ( | |
80 | transparency(CPU_SYS, AREA_OPACITY), | |
81 | LABEL % _("System"), | |
82 | ), | |
83 | "GPRINT:sys_p_cur:%s" % PERCENTAGE, | |
84 | "GPRINT:sys_p_avg:%s" % PERCENTAGE, | |
85 | "GPRINT:sys_p_min:%s" % PERCENTAGE, | |
86 | "GPRINT:sys_p_max:%s\\j" % PERCENTAGE, | |
87 | ||
88 | "CDEF:wait_p=100,wait,*,total,/", | |
89 | "AREA:wait_p%s:%s:STACK" % ( | |
90 | transparency(CPU_WAIT, AREA_OPACITY), | |
91 | LABEL % _("Wait"), | |
92 | ), | |
93 | "GPRINT:wait_p_cur:%s" % PERCENTAGE, | |
94 | "GPRINT:wait_p_avg:%s" % PERCENTAGE, | |
95 | "GPRINT:wait_p_min:%s" % PERCENTAGE, | |
96 | "GPRINT:wait_p_max:%s\\j" % PERCENTAGE, | |
97 | ||
98 | "CDEF:irq_p=100,irq,*,total,/", | |
99 | "AREA:irq_p%s:%s:STACK" % ( | |
100 | transparency(CPU_IRQ, AREA_OPACITY), | |
101 | LABEL % _("Interrupt"), | |
102 | ), | |
103 | "GPRINT:irq_p_cur:%s" % PERCENTAGE, | |
104 | "GPRINT:irq_p_avg:%s" % PERCENTAGE, | |
105 | "GPRINT:irq_p_min:%s" % PERCENTAGE, | |
106 | "GPRINT:irq_p_max:%s\\j" % PERCENTAGE, | |
107 | ||
108 | "CDEF:sirq_p=100,sirq,*,total,/", | |
109 | "AREA:sirq_p%s:%s:STACK" % ( | |
110 | transparency(CPU_SIRQ, AREA_OPACITY), | |
111 | LABEL % _("Soft Interrupt"), | |
112 | ), | |
113 | "GPRINT:sirq_p_cur:%s" % PERCENTAGE, | |
114 | "GPRINT:sirq_p_avg:%s" % PERCENTAGE, | |
115 | "GPRINT:sirq_p_min:%s" % PERCENTAGE, | |
116 | "GPRINT:sirq_p_max:%s\\j" % PERCENTAGE, | |
117 | ||
118 | "CDEF:steal_p=100,steal,*,total,/", | |
119 | "AREA:steal_p%s:%s:STACK" % ( | |
120 | transparency(CPU_STEAL, AREA_OPACITY), | |
121 | LABEL % _("Steal"), | |
122 | ), | |
123 | "GPRINT:steal_p_cur:%s" % PERCENTAGE, | |
124 | "GPRINT:steal_p_avg:%s" % PERCENTAGE, | |
125 | "GPRINT:steal_p_min:%s" % PERCENTAGE, | |
126 | "GPRINT:steal_p_max:%s\\j" % PERCENTAGE, | |
127 | ||
128 | "CDEF:guest_p=100,guest,*,total,/", | |
129 | "AREA:guest_p%s:%s:STACK" % ( | |
130 | transparency(CPU_GUEST, AREA_OPACITY), | |
131 | LABEL % _("Guest"), | |
132 | ), | |
133 | "GPRINT:guest_p_cur:%s" % PERCENTAGE, | |
134 | "GPRINT:guest_p_avg:%s" % PERCENTAGE, | |
135 | "GPRINT:guest_p_min:%s" % PERCENTAGE, | |
136 | "GPRINT:guest_p_max:%s\\j" % PERCENTAGE, | |
137 | ||
138 | "CDEF:guest_nice_p=100,guest_nice,*,total,/", | |
139 | "AREA:guest_nice_p%s:%s:STACK" % ( | |
140 | transparency(CPU_GUEST_NICE, AREA_OPACITY), | |
141 | LABEL % _("Guest Nice"), | |
142 | ), | |
143 | "GPRINT:guest_nice_p_cur:%s" % PERCENTAGE, | |
144 | "GPRINT:guest_nice_p_avg:%s" % PERCENTAGE, | |
145 | "GPRINT:guest_nice_p_min:%s" % PERCENTAGE, | |
146 | "GPRINT:guest_nice_p_max:%s\\j" % PERCENTAGE, | |
147 | ||
148 | "CDEF:idle_p=100,idle,*,total,/", | |
149 | "AREA:idle_p%s::STACK" % CPU_IDLE, | |
150 | ||
151 | # Draw contour lines | |
152 | "LINE:user_p%s" % CPU_USER, | |
153 | "LINE:nice_p%s::STACK" % CPU_NICE, | |
154 | "LINE:sys_p%s::STACK" % CPU_SYS, | |
155 | "LINE:wait_p%s::STACK" % CPU_WAIT, | |
156 | "LINE:irq_p%s::STACK" % CPU_IRQ, | |
157 | "LINE:sirq_p%s::STACK" % CPU_SIRQ, | |
158 | "LINE:steal_p%s::STACK" % CPU_STEAL, | |
159 | "LINE:guest_p%s::STACK" % CPU_GUEST, | |
160 | "LINE:guest_nice_p%s::STACK" % CPU_GUEST_NICE, | |
161 | ] | |
162 | ||
163 | upper_limit = 100 | |
164 | lower_limit = 0 | |
165 | ||
166 | @property | |
167 | def graph_title(self): | |
168 | return _("Processor Usage") | |
169 | ||
170 | @property | |
171 | def graph_vertical_label(self): | |
172 | return _("Percent") | |
173 | ||
174 | ||
175 | class ProcessorObject(base.Object): | |
176 | rrd_schema = [ | |
177 | "DS:user:DERIVE:0:U", | |
178 | "DS:nice:DERIVE:0:U", | |
179 | "DS:sys:DERIVE:0:U", | |
180 | "DS:idle:DERIVE:0:U", | |
181 | "DS:wait:DERIVE:0:U", | |
182 | "DS:irq:DERIVE:0:U", | |
183 | "DS:sirq:DERIVE:0:U", | |
184 | "DS:steal:DERIVE:0:U", | |
185 | "DS:guest:DERIVE:0:U", | |
186 | "DS:guest_nice:DERIVE:0:U", | |
187 | ] | |
188 | ||
189 | def init(self, cpu_id=None): | |
190 | self.cpu_id = cpu_id | |
191 | ||
192 | @property | |
193 | def id(self): | |
194 | if self.cpu_id is not None: | |
195 | return "%s" % self.cpu_id | |
196 | ||
197 | return "default" | |
198 | ||
199 | def collect(self): | |
200 | """ | |
201 | Reads the CPU usage. | |
202 | """ | |
203 | stat = self.read_proc_stat() | |
204 | ||
205 | if self.cpu_id is None: | |
206 | values = stat.get("cpu") | |
207 | else: | |
208 | values = stat.get("cpu%s" % self.cpu_id) | |
209 | ||
210 | # Convert values into a list | |
211 | values = values.split() | |
212 | ||
213 | if not len(values) == len(self.rrd_schema): | |
214 | raise ValueError("Received unexpected output from /proc/stat: %s" % values) | |
215 | ||
216 | return values | |
217 | ||
218 | ||
219 | class ProcessorPlugin(base.Plugin): | |
220 | name = "processor" | |
221 | description = "Processor Usage Plugin" | |
222 | ||
223 | templates = [GraphTemplateProcessor] | |
224 | ||
225 | @property | |
226 | def objects(self): | |
227 | yield ProcessorObject(self) | |
228 | ||
229 | num = multiprocessing.cpu_count() | |
230 | for i in range(num): | |
231 | yield ProcessorObject(self, cpu_id=i) |