1 # -*- coding: utf-8 -*-
2 # Description: cpufreq netdata python.d module
3 # Author: Pawel Krupa (paulfantom) and Steven Noonan (tycho)
8 from base import SimpleService
10 # default module values (can be overridden per job in `config`)
17 'options': [None, 'CPU Clock', 'MHz', 'cpufreq', None, 'line'],
19 # lines are created dynamically in `check()` method
23 class Service(SimpleService):
24 def __init__(self, configuration=None, name=None):
25 prefix = os.getenv('NETDATA_HOST_PREFIX', "")
26 if prefix.endswith('/'):
28 self.sys_dir = prefix + "/sys/devices"
29 SimpleService.__init__(self, configuration=configuration, name=name)
31 self.definitions = CHARTS
34 self.accurate_exists = True
35 self.accurate_last = {}
40 if self.accurate_exists:
41 elapsed = time.time() - self.timetable['last']
45 for name, paths in self.assignment.items():
46 last = self.accurate_last[name]
48 for line in open(paths['accurate'], 'r'):
49 line = list(map(int, line.split()))
50 current += (line[0] * line[1]) / 100
51 delta = current - last
53 self.accurate_last[name] = current
54 if delta == 0 or abs(delta) > 1e7:
55 # Delta is either too large or nonexistent, fall back to
56 # less accurate reading. This can happen if we switch
57 # to/from the 'schedutil' governor, which doesn't report
64 self.alert("accurate method failed, falling back")
65 self.accurate_exists = False
68 for name, paths in self.assignment.items():
69 data[name] = open(paths['inaccurate'], 'r').read()
75 self.sys_dir = str(self.configuration['sys_dir'])
76 except (KeyError, TypeError):
77 self.error("No path specified. Using: '" + self.sys_dir + "'")
79 self._orig_name = self.chart_name
81 for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/stats/time_in_state'):
82 path_elem = path.split('/')
84 if cpu not in self.assignment:
85 self.assignment[cpu] = {}
86 self.assignment[cpu]['accurate'] = path
87 self.accurate_last[cpu] = 0
89 if len(self.assignment) == 0:
90 self.accurate_exists = False
92 for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/scaling_cur_freq'):
93 path_elem = path.split('/')
95 if cpu not in self.assignment:
96 self.assignment[cpu] = {}
97 self.assignment[cpu]['inaccurate'] = path
99 if len(self.assignment) == 0:
100 self.error("couldn't find a method to read cpufreq statistics")
103 for name in self.assignment.keys():
104 self.definitions[ORDER[0]]['lines'].append([name, name, 'absolute', 1, 1000])
109 self.chart_name = "cpu"
110 status = SimpleService.create(self)
111 self.chart_name = self._orig_name
114 def update(self, interval):
115 self.chart_name = "cpu"
116 status = SimpleService.update(self, interval=interval)
117 self.chart_name = self._orig_name