Completed
Push — master ( c845e9...7e8cc2 )
by Kenny
02:02
created

VmStat   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

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

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 14 1
B check() 0 39 6
A poll() 0 6 1
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_list
15
16
17
class VmStat(plumd.plugins.Reader):
18
    """Plugin to measure various kernel metrics from /proc/vmstat."""
19
    defaults = {
20
        'poll.interval': 10,
21
        'proc_path': '/proc',
22
        # awk '{ print "\"" $1 "\"," }' /proc/vmstat
23
        'proc_vmstat_gauges': ["nr_free_pages", "nr_dirtied", "nr_written",
24
                               "numa_hit", "numa_miss", "numa_foreign",
25
                               "numa_interleave", "numa_local", "numa_other",
26
                               "pgpgin", "pgpgout", "pswpin", "pswpout",
27
                               "pgalloc_dma", "pgalloc_dma32", "pgalloc_normal",
28
                               "pgalloc_movable", "pgfree", "pgactivate",
29
                               "pgdeactivate", "pgfault", "pgmajfault",
30
                               "slabs_scanned", "kswapd_inodesteal",
31
                               "kswapd_low_wmark_hit_quickly",
32
                               "kswapd_high_wmark_hit_quickly",
33
                               "drop_pagecache", "drop_slab",
34
                               "numa_pte_updates", "numa_huge_pte_updates",
35
                               "numa_hint_faults", "numa_hint_faults_local",
36
                               "numa_pages_migrated", "pgmigrate_success",
37
                               "pgmigrate_fail", "compact_migrate_scanned",
38
                               "compact_free_scanned", "compact_isolated",
39
                               "compact_stall", "compact_fail",
40
                               "compact_success"],
41
        'proc_vmstat_rates': []
42
    }
43
44
    def __init__(self, log, config):
45
        """Plugin to measure various kernel metrics from /proc/vmstat.
46
47
        :param log: A logger
48
        :type log: logging.RootLogger
49
        :param config: a plumd.config.Conf configuration helper instance.
50
        :type config: plumd.config.Conf
51
        """
52
        super(VmStat, self).__init__(log, config)
53
        self.config.defaults(VmStat.defaults)
54
        self.calc = Differential()
55
        self.proc_file = "{0}/vmstat".format(config.get('proc_path'))
56
        self.gauges = self.config.get('proc_vmstat_gauges')
57
        self.rates = self.config.get('proc_vmstat_rates')
58
59
60
    def poll(self):
61
        """Poll for kernel metrics under proc file net/netstat.
62
63
        :rtype: ResultSet
64
        """
65
        return plumd.ResultSet(self.check())
66
67
68
    def check(self):
69
        """Return metrics from /proc/vmstat.
70
71
        :rtype: plumd.Result
72
        """
73
        # what metrics do we want to record?
74
        result = plumd.Result("vmstat")
75
76
        # read the proc file
77
        dat = {}
78
        with open(self.proc_file, 'r') as f:
79
            # get a list of values: metric, val, metric, val, etc
80
            vals = f.read().strip().split()
81
            # every second item starting at 0, every second item starting at 1
82
            # take that and put into a dict
83
            dat = dict(zip(vals[0::2], vals[1::2]))
84
85
        # timestamp for Differential calculations
86
        ts = time.time()
87
88
        # now, we have a list of items to record, just need to record them
89
        for i, metric in enumerate(self.gauges):
90
            if metric in dat:
91
                #mval = self.calc.per_second(mstr, int(values[mname]), ts)
92
                result.add(plumd.Int(metric, dat[metric]))
93
            else:
94
                self.log.warn("netstat: unknown metric {0}".format(metric))
95
                del(self.gauges[i])
96
97
        # and the rates as well, if any
98
        for i, metric in enumerate(self.rates):
99
            if metric in dat:
100
                mval = self.calc.per_second(mstr, int(dat[metric]), ts)
101
                result.add(plumd.Float(metric, mval))
102
            else:
103
                self.log.warn("netstat: unknown metric {0}".format(metric))
104
                del(self.rates[i])
105
106
        return [result]
107