Completed
Push — master ( 2732fd...68eb58 )
by Kenny
02:49
created

DiskSpace.__init__()   B

Complexity

Conditions 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 4
c 1
b 1
f 0
dl 0
loc 22
rs 8.9197
1
# -*- coding: utf-8 -*-
2
3
__author__ = 'Kenny Freeman'
4
__email__ = '[email protected]'
5
__license__ = "ISCL"
6
__docformat__ = 'reStructuredText'
7
8
import re
9
import os
10
import sys
11
12
PY3 = sys.version_info > (3,)
13
14
import plumd
15
import plumd.plugins
16
from plumd.util import get_file_list
17
18
19
class DiskSpace(plumd.plugins.Reader):
20
    """Plugin to measure disk usage."""
21
22
    # default config values
23
    defaults = {
24
        'poll.interval': 60,
25
        'fs_types': ['xfs', 'ext2', 'ext3', 'ext4'],
26
        'mnt_exclude_re': "^\/mnt\/.*",
27
        'chrs_keep': 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-'
28
    }
29
30
    def __init__(self, log, config):
31
        """Plugin to measure disk usage.
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(DiskSpace, self).__init__(log, config)
39
        self.config.defaults(DiskSpace.defaults)
40
        # skip mounts for devices matching this re
41
        self.mnt_re = re.compile(config.get('mnt_exclude_re'))
42
43
        # characters to remove from device names
44
        self.filter_chars = "".join(char for char in map(chr, range(256)) \
45
                                    if char not in self.config.get('chrs_keep'))
46
        # args for str.translate() calls
47
        self.tlate_args = [None, self.filter_chars]
48
        if PY3:
49
            self.tlate_args = [dict.fromkeys(map(ord, self.filter_chars)), None]
50
        # get a list of mount points - only on init
51
        self.mounts = self.proc_mounts()
52
53
    def proc_mounts(self):
54
        fs_types = self.config.get('fs_types')
55
        ret = []
56
        mounts = get_file_list("/proc/mounts")
57
        filter_chars = self.filter_chars
58
        mnt_re = self.mnt_re
59
        tlate_args = self.tlate_args
60
        for entry in mounts:
61
            dev, path, fs, opts, d1, d2 = entry.split()
62
            if mnt_re.match(dev) or fs not in fs_types:
63
                continue
64
            dev = re.sub("^/dev/", "", dev)
65
            dev = dev.translate(*tlate_args)
66
            ret.append((dev, path))
67
        return ret
68
69
70
    def poll(self):
71
        """Poll for disk space usage.
72
73
        :rtype: ResultSet
74
        """
75
        result = plumd.Result("diskusage")
76
        for dev, mpoint in self.mounts:
77
            mp_stat = os.statvfs(mpoint)
78
            free = (mp_stat.f_bavail * mp_stat.f_frsize)
79
            total = (mp_stat.f_blocks * mp_stat.f_frsize)
80
            used = (mp_stat.f_blocks - mp_stat.f_bfree) * mp_stat.f_frsize
81
            total_inodes = mp_stat.f_files
82
            free_inodes = mp_stat.f_favail
83
            used_inodes = total_inodes - free_inodes
84
            result.add(plumd.Int("{0}.free".format(dev), free))
85
            result.add(plumd.Int("{0}.total".format(dev), total))
86
            result.add(plumd.Int("{0}.used".format(dev), used))
87
            result.add(plumd.Int("{0}.total_inodes".format(dev), total_inodes))
88
            result.add(plumd.Int("{0}.free_inodes".format(dev), free_inodes))
89
            result.add(plumd.Int("{0}.used_inodes".format(dev), used_inodes))
90
        return plumd.ResultSet([result])
91