DiskStats   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 10
c 2
b 0
f 0
dl 0
loc 74
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
B __init__() 0 29 4
A poll() 0 6 1
B check() 0 23 5
1
# -*- coding: utf-8 -*-
2
"""Disk io stats reader from /proc on Linux."""
3
import re
4
import time
5
6
import plumd
7
from plumd.util import Differential
8
from plumd.util import get_file_map, get_file
9
10
__author__ = 'Kenny Freeman'
11
__email__ = '[email protected]'
12
__license__ = "ISCL"
13
__docformat__ = 'reStructuredText'
14
15
16
class DiskStats(plumd.Reader):
17
    """Plugin to measure various kernel metrics from /proc."""
18
19
    proc_colums = 14
20
21
    defaults = {
22
        'poll.interval': 10,
23
        'proc_path': '/proc',
24
        'diskstats_dev_re': "dm-\d",
0 ignored issues
show
Bug introduced by
A suspicious escape sequence \d was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
25
        'diskstats_cols': ["r", "r_merge", "r_sector", "r_time", "w", "w_merge",
26
                           "w_sector", "w_time", "io_inprog", "io_time",
27
                           "io_weighted_time"]
28
    }
29
30
    def __init__(self, log, config):
31
        """Plugin to measure various kernel metrics from /proc.
32
33
        :param log: A logger
34
        :type log: logging.RootLogger
35
        :param config: a plumd.config.Conf configuration helper instance.
36
        :type config: plumd.config.Conf
37
        """
38
        super(DiskStats, self).__init__(log, config)
39
        config.defaults(DiskStats.defaults)
40
        self.calc = Differential()
41
        self.proc_file = "{0}/diskstats".format(config.get('proc_path'))
42
        self.diskstats_dev_re = re.compile(config.get('diskstats_dev_re'))
43
        self.diskstats_cols = self.config.get('diskstats_cols')
44
        self.devices = []  # list of device names to record metrics for
45
        self.enabled = True
46
        # get list of available devices:
47
        dat = get_file_map(self.proc_file, 2, 0)
48
        # key is the device name, exclude ones matching the re
49
        for key in dat.keys():
50
            if not self.diskstats_dev_re.match(key):
51
                self.devices.append(key)
52
        # check format of proc file
53
        ncols = len(get_file(self.proc_file).split("\n")[0].split())
54
        self.enabled = ncols == DiskStats.proc_colums
55
        if not self.enabled:
56
            msg = "DiskStats: invalid format: {0} has {1} cols, not {2}"
57
            self.log.error(msg.format(self.proc_file, ncols,
58
                                      DiskStats.proc_colums))
59
60
    def poll(self):
61
        """Poll for kernel metrics under /proc.
62
63
        :rtype: ResultSet
64
        """
65
        return plumd.ResultSet(self.check())
66
67
    def check(self):
68
        """Return disk io metrics from proc file diskstats.
69
70
        :rtype: plumd.Result
71
        """
72
        # times in ms
73
        cols = self.diskstats_cols
74
        result = plumd.Result("diskstats")
75
        if not self.enabled:
76
            return [result]
77
        dat = {}
78
        # read and process /proc/diskstats
79
        dat = get_file_map(self.proc_file, 2, 0)
80
        times = time.time()
81
        for dev in self.devices:
82
            if dev not in dat:
83
                continue
84
            for mname in cols:
85
                mval = float(dat[dev].popleft())
86
                mstr = "{0}.{1}".format(dev, mname)
87
                dval = self.calc.per_second(mstr, mval, times)
88
                result.add(plumd.Float(mstr, dval))
89
        return [result]
90