]> git.ipfire.org Git - collecty.git/blob - src/collecty/plugins/cpufreq.py
graphs: Justify all legends
[collecty.git] / src / collecty / plugins / cpufreq.py
1 #!/usr/bin/python3
2 ###############################################################################
3 # #
4 # collecty - A system statistics collection daemon for IPFire #
5 # Copyright (C) 2015 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 os
23 import re
24
25 from . import base
26
27 class GraphTemplateCPUFreq(base.GraphTemplate):
28 name = "cpufreq"
29
30 lower_limit = 0
31
32 def get_objects(self, *args, **kwargs):
33 return list(self.plugin.objects)
34
35 @property
36 def graph_title(self):
37 _ = self.locale.translate
38 return _("Processor Frequencies")
39
40 @property
41 def graph_vertical_label(self):
42 _ = self.locale.translate
43 return "%s [%s]" % (_("Frequency"), _("Hz"))
44
45 processor_colours = [
46 "#ff000066",
47 "#00ff0066",
48 "#0000ff66",
49 "#ffff0066",
50 ]
51
52 @property
53 def rrd_graph(self):
54 rrd_graph = []
55
56 for processor, colour in zip(self.objects, self.processor_colours):
57 rrd_graph += processor.make_rrd_defs(processor.id) + [
58 "LINE2:%s_current%s:%-10s" % (processor.id, colour, processor.name),
59 "GPRINT:%s_current_avg:%%6.2lf %%sHz" % processor.id,
60 ]
61
62 return rrd_graph
63
64 rrd_graph_args = [
65 "--base", "1000", # Hz
66 ]
67
68
69 class CPUFreqObject(base.Object):
70 rrd_schema = [
71 "DS:current:GAUGE:0:U",
72 "DS:minimum:GAUGE:0:U",
73 "DS:maximum:GAUGE:0:U",
74 ]
75
76 def __repr__(self):
77 return "<%s %s>" % (self.__class__.__name__, self.cpuid)
78
79 def init(self, cpuid):
80 self.cpuid = cpuid
81
82 self.sys_path = os.path.join("/sys/devices/system/cpu", self.cpuid)
83
84 @property
85 def name(self):
86 return "Core %s" % self.core_id
87
88 @property
89 def id(self):
90 return self.cpuid
91
92 @property
93 def core_id(self):
94 return self.read_file(self.sys_path, "topology/core_id")
95
96 def is_cpufreq_supported(self):
97 path = os.path.join(self.sys_path, "cpufreq")
98
99 return os.path.exists(path)
100
101 def collect(self):
102 return (
103 self.read_frequency("cpufreq/cpuinfo_cur_freq"),
104 self.read_frequency("cpufreq/cpuinfo_min_freq"),
105 self.read_frequency("cpufreq/cpuinfo_max_freq"),
106 )
107
108 def read_frequency(self, filename):
109 val = self.read_file(self.sys_path, filename)
110
111 # Convert from kHz to Hz
112 return int(val) * 1000
113
114
115 class CPUFreqPlugin(base.Plugin):
116 name = "cpufreq"
117 description = "cpufreq Plugin"
118
119 templates = [GraphTemplateCPUFreq]
120
121 @property
122 def objects(self):
123 core_ids = []
124
125 for cpuid in os.listdir("/sys/devices/system/cpu"):
126 if not re.match(r"cpu[0-9]+", cpuid):
127 continue
128
129 o = CPUFreqObject(self, cpuid)
130
131 # If we have already seen a virtual core of the processor,
132 # we will skip any others.
133 if o.core_id in core_ids:
134 continue
135
136 # Check if this processor is supported by cpufreq
137 if not o.is_cpufreq_supported():
138 continue
139
140 # Save the ID of the added core
141 core_ids.append(o.core_id)
142
143 yield o