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

NetSnmp.check()   C

Complexity

Conditions 7

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
c 1
b 0
f 0
dl 0
loc 39
rs 5.5
1
# -*- coding: utf-8 -*-
2
3
__author__ = 'Kenny Freeman'
4
__email__ = '[email protected]'
5
__license__ = "ISCL"
6
__docformat__ = 'reStructuredText'
7
8
import time
9
import traceback
10
from collections import deque
11
12
import plumd
13
import plumd.plugins
14
from plumd.calc import Differential
15
from plumd.util import get_file_list, Filter
16
17
18
## todo: switch from list with pop(0) to deque
19
class NetSnmp(plumd.plugins.Reader):
20
    """Plugin to measure various kernel metrics from /proc."""
21
    defaults = {
22
        'poll.interval': 10,
23
        'proc_path': '/proc',
24
        'skip_proc_net_snmp': ["Icmp.InAddrMaskReps","Icmp.InAddrMasks",
25
            "Icmp.InTimestampReps","Icmp.InTimestamps","Icmp.OutAddrMaskReps",
26
            "Icmp.OutAddrMasks","Icmp.OutTimestampReps","Icmp.OutTimestamps",
27
            "Ip.DefaultTTL","Ip.Forwarding","Tcp.MaxConn","Tcp.RtoAlgorithm",
28
            "Tcp.RtoMax","Tcp.RtoMin"]
29
    }
30
31
    def __init__(self, log, config):
32
        """Plugin to measure various kernel metrics from /proc.
33
34
        :param log: A logger
35
        :type log: logging.RootLogger
36
        :param config: a plumd.config.Conf configuration helper instance.
37
        :type config: plumd.config.Conf
38
        """
39
        super(NetSnmp, self).__init__(log, config)
40
        self.config.defaults(NetSnmp.defaults)
41
        self.calc = Differential()
42
        self.proc_file = "{0}/net/snmp".format(config.get('proc_path'))
43
        self.filter = Filter()
44
45
46
47
    def poll(self):
48
        """Poll for kernel metrics under /proc.
49
50
        :rtype: ResultSet
51
        """
52
        return plumd.ResultSet(self.check())
53
54
55
    def check(self):
56
        """Return network protocol metrics from proc file net/snmp.
57
58
        Add entries to the configuration value 'skip_proc_net_snmp' to skip
59
        metrics.
60
61
        Add entries to the configuration value 'net_snmp_items' to match the
62
        format/order of the proc file net/snmp entries on the system.
63
64
        :rtype: plumd.Result
65
        """
66
        skip = self.config.get('skip_proc_net_snmp')
67
        result = plumd.Result("net_snmp")
68
        dat = {}
69
        # read and process - dat is a list of lines from fname
70
        dat = get_file_list(self.proc_file)
71
        ts = time.time()
72
        vals = True
73
        # process each pair of lines
74
        while dat and vals:
75
            try:
76
                # first line is a list of: metric: header values
77
                header = deque(dat.popleft().split())
78
                # second line is a list of: <metric>: metric values
79
                vals = deque([ int(i) for i in dat.popleft().split()[1:] ])
80
            except Exception as e:
81
                tb = traceback.format_exc()
82
                self.log.error("proc_net_snmp: exception: {0}: {1}".format(e, tb))
83
                continue
84
            # first value is the name of the metric eg. Ip, Icmp, etc
85
            mheader = self.filter.process(header.popleft())
86
            for mname in header:
87
                mval = vals.popleft()
88
                mstr = "{0}.{1}".format(mheader, mname)
89
                if mstr in skip:
90
                    continue
91
                dval = self.calc.per_second(mstr, mval, ts)
92
                result.add(plumd.Int(mstr, dval))
93
        return [result]
94