Completed
Branch master (2f3d56)
by Kenny
01:12
created

Stat.proc_stat_cpu_percent()   A

Complexity

Conditions 4

Size

Total Lines 20

Duplication

Lines 20
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
c 1
b 0
f 0
dl 20
loc 20
rs 9.2
1
# -*- coding: utf-8 -*-
2
3
__author__ = 'Kenny Freeman'
4
__email__ = '[email protected]'
5
__license__ = "ISCL"
6
__docformat__ = 'reStructuredText'
7
8
import time
9
from collections import deque
10
11
import plumd
12
import plumd.plugins
13
from plumd.calc import Differential
14
from plumd.util import get_file_map
15
16
17
## todo: switch from list with pop(0) to deque
18
class Stat(plumd.plugins.Reader):
19
    """Class to read metrics from /proc/stat"""
20
    defaults = {
21
        'cpu_metrics': ["user", "nice", "system", "idle", "iowait", "irq",
22
                        "softirq","steal", "guest", "guest_nice"],
23
        'per_cpu': False,
24
    }
25
26
    def __init__(self, log, config):
27
        """Plugin to measure various kernel metrics from /proc/stat
28
29
        :param log: A logger
30
        :type log: logging.RootLogger
31
        :param config: a plumd.config.Conf configuration helper instance.
32
        :type config: plumd.config.Conf
33
        """
34
        super(Stat, self).__init__(log, config)
35
        config.defaults(Stat.defaults)
36
        self.calc = Differential()
37
        self.proc_file = "{0}/stat".format(config.get('proc_path'))
38
        self.per_cpu = config.get('per_cpu')
39
        self.cpu_metrics = config.get('cpu_metrics')
40
41
42
    def poll(self):
43
        """Return cpu utilization and process metrics from proc file stat.
44
45
        :rtype: plumd.ResultSet
46
        """
47
        return plumd.ResultSet(self.check())
48
49
50
    def check(self):
51
        """Return cpu utilization and process metrics from proc file stat.
52
53
        :rtype: collections.deque
54
        """
55
        per_cpu = self.per_cpu
56
        results = deque()
57
        result = plumd.Result("stat")
58
        dat = get_file_map(self.proc_file, 0, 0)
59
        ts = time.time()
60
        # parse
61
        for key, val in dat.items():
62
            # cpu and btime are the only special metrics
63
            if key == "btime":
64
                result.add(plumd.Int(key, val[0]))
65
            elif key == "cpu":
66
                results.append(self.proc_stat_cpu_percent(key, val, ts))
67
            elif per_cpu and key.startswith("cpu"):
68
                results.append(self.proc_stat_cpu_percent(key, val, ts))
69
            else:
70
                # val will be a list, take the first item from it
71
                mval = self.calc.per_second(key, float(val[0]), ts)
72
                result.add(plumd.Int(key, mval))
73
        results.append(result)
74
        return results
75
76
77 View Code Duplication
    def proc_stat_cpu_percent(self, key, val, ts):
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
78
        """Return cpu utilization metrics in percentage.
79
80
        :param key: The metric name (eg. cpu, cpu0, cpu1, etc)
81
        :type key: str
82
        :param val: A deque populated with the metric values from stat
83
        :type val: deque
84
        :rtype: list
85
        """
86
        result = plumd.Result("cpu")
87
        total = sum([ float(i) for i in val])
88
        cpu = self.config.get('cpu_metrics')
89
        for map_val in cpu:
90
            if len(val) < 1:
91
                break
92
            metric_val = float(val.popleft())
93
            mstr = "{0}_{1}".format(key, map_val)
94
            percent_val = metric_val / total * 100.00
95
            result.add(plumd.Float(mstr, percent_val))
96
        return result
97
98
99 View Code Duplication
    def proc_stat_cpu(self, key, val, ts):
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
100
        """Return cpu utilization metrics in USER_HZ or Jiffies
101
        (most likely units of 100Hz intervals ie. 100ms intervals).
102
103
        :param key: The metric name (eg. cpu, cpu0, cpu1, etc)
104
        :type key: str
105
        :param val: A deque populated with the metric values from stat
106
        :type val: deque
107
        :rtype: list
108
        """
109
        result = plumd.Result("cpus")
110
        total = sum([ float(i) for i in val])
111
        cpu = self.config.get('cpu_metrics')
112
        for map_val in cpu:
113
            if len(val) < 1:
114
                break
115
            metric_val = float(val.popleft())
116
            mstr = "{0}_{1}".format(key, map_val)
117
            percent_val = float(metric_val / total) * 100.00
118
            mval = self.calc.per_second(key, percent_val, ts)
119
            result.add(plumd.Float(mstr, mval))
120
        return result
121