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")
67 for name, paths in self.assignment.items():
68 data[name] = open(paths['inaccurate'], 'r').read()
74 self.sys_dir = str(self.configuration['sys_dir'])
75 except (KeyError, TypeError):
76 self.error("No path specified. Using: '" + self.sys_dir + "'")
78 self._orig_name = self.chart_name
80 for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/stats/time_in_state'):
81 path_elem = path.split('/')
83 if cpu not in self.assignment:
84 self.assignment[cpu] = {}
85 self.assignment[cpu]['accurate'] = path
86 self.accurate_last[cpu] = 0
88 if len(self.assignment) == 0:
89 self.accurate_exists = False
91 for path in glob.glob(self.sys_dir + '/system/cpu/cpu*/cpufreq/scaling_cur_freq'):
92 path_elem = path.split('/')
94 if cpu not in self.assignment:
95 self.assignment[cpu] = {}
96 self.assignment[cpu]['inaccurate'] = path
98 if len(self.assignment) == 0:
99 self.error("couldn't find a method to read cpufreq statistics")
102 for name in self.assignment.keys():
103 self.definitions[ORDER[0]]['lines'].append([name, name, 'absolute', 1, 1000])
108 self.chart_name = "cpu"
109 status = SimpleService.create(self)
110 self.chart_name = self._orig_name
113 def update(self, interval):
114 self.chart_name = "cpu"
115 status = SimpleService.update(self, interval=interval)
116 self.chart_name = self._orig_name