Completed
Push — master ( bf7745...a37b9e )
by Kenny
01:26
created

Stat   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 97
Duplicated Lines 16.49 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 16
loc 97
rs 10
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
A poll() 0 6 1
F check() 0 42 9
A proc_stat_cpu() 0 17 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
        'proc_stat_gauges': ['procs_running', 'procs_blocked'],
22
        'proc_stat_rates': ['intr', 'ctxt', 'softirq'],
23
        'cpu_metrics': ["user", "nice", "system", "idle", "iowait", "irq",
24
                        "softirq","steal", "guest", "guest_nice"],
25
        'per_cpu': False,
26
    }
27
28 View Code Duplication
    def __init__(self, log, config):
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
29
        """Plugin to measure various kernel metrics from /proc/stat
30
31
        :param log: A logger
32
        :type log: logging.RootLogger
33
        :param config: a plumd.config.Conf configuration helper instance.
34
        :type config: plumd.config.Conf
35
        """
36
        super(Stat, self).__init__(log, config)
37
        self.config.defaults(Stat.defaults)
38
        self.calc = Differential()
39
        self.proc_file = "{0}/stat".format(config.get('proc_path'))
40
        self.per_cpu = self.config.get('per_cpu')
41
        self.cpu_metrics = self.config.get('cpu_metrics')
42
        self.gauges = self.config.get('proc_stat_gauges')
43
        self.rates = self.config.get('proc_stat_rates')
44
45
46
    def poll(self):
47
        """Return cpu utilization and process metrics from proc file stat.
48
49
        :rtype: plumd.ResultSet
50
        """
51
        return plumd.ResultSet(self.check())
52
53
54
    def check(self):
55
        """Return cpu utilization and process metrics from proc file stat.
56
57
        :rtype: collections.deque
58
        """
59
        results = deque()
60
        result = plumd.Result("stat")
61
62
        dat = get_file_map(self.proc_file, 0, 0)
63
        ts = time.time()
64
65
        # record gauges
66
        for i, metric in enumerate(self.gauges):
67
            if metric not in dat:
68
                self.log.warn("stat: unknown metric {0}".format(metric))
69
                del(self.gauges[i])
70
                continue
71
            result.add(plumd.Int(metric, dat[metric][0]))
72
73
        # record rates
74
        for i, metric in enumerate(self.rates):
75
            if metric not in dat:
76
                self.log.warn("stat: unknown metric {0}".format(metric))
77
                del(self.rates[i])
78
                continue
79
            mval = self.calc.per_second(metric, float(dat[metric][0]), ts)
80
            result.add(plumd.Int(metric, mval))
81
82
        # record cpu
83
        if "cpu" in dat:
84
            results.append(self.proc_stat_cpu("cpu", "cpu", dat["cpu"]))
85
86
        # record each cpu if configured
87
        if self.per_cpu:
88
            for i in xrange(0, len(dat)):
89
                mstr = "cpu{0}".format(i)
90
                if mstr not in dat:
91
                    break
92
                results.append(self.proc_stat_cpu("cpus", mstr, dat[mstr]))
93
94
        results.append(result)
95
        return results
96
97
98
    def proc_stat_cpu(self, rname, key, val):
99
        """Return cpu utilization metrics in percentage.
100
101
        :param rname: The Result name (eg. cpu or cpus)
102
        :type rname: str
103
        :param val: A deque populated with the metric values from stat
104
        :type val: deque
105
        :rtype: list
106
        """
107
        result = plumd.Result(rname)
108
        cpu = self.cpu_metrics
109
        for map_val in cpu:
110
            if not val:
111
                break
112
            mstr = "{0}_{1}".format(key, map_val)
113
            result.add(plumd.Float(mstr, val.popleft()))
114
        return result
115