Completed
Branch master (7e8cc2)
by Kenny
03:21 queued 19s
created

SockStat.check()   B

Complexity

Conditions 6

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
c 1
b 0
f 0
dl 0
loc 35
rs 7.5384
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_list, get_file, Filter
15
16
17
class SockStat(plumd.plugins.Reader):
18
    """Plugin to measure various kernel metrics from /proc."""
19
    defaults = {
20
        'poll.interval': 10,
21
        'proc_path': '/proc'
22
    }
23
24
    def __init__(self, log, config):
25
        """Plugin to measure various kernel metrics from /proc.
26
27
        :param log: A logger
28
        :type log: logging.RootLogger
29
        :param config: a plumd.config.Conf configuration helper instance.
30
        :type config: plumd.config.Conf
31
        """
32
        super(SockStat, self).__init__(log, config)
33
        self.config.defaults(SockStat.defaults)
34
        self.calc = Differential()
35
        proc_path = config.get('proc_path')
36
        self.proc_file = "{0}/net/sockstat".format(proc_path)
37
        # sys/net/ipv4/tcp_mem format: min, pressure, max
38
        self.fname_limits = "{0}/sys/net/ipv4/tcp_mem".format(proc_path)
39
        # orphan limit: /proc/sys/net/ipv4/tcp_max_orphans
40
        self.fname_orph = "{0}/sys/net/ipv4/tcp_max_orphans".format(proc_path)
41
        self.filter = Filter()
42
43
44
    def poll(self):
45
        """Poll for kernel metrics under /proc.
46
47
        :rtype: ResultSet
48
        """
49
        return plumd.ResultSet(self.check())
50
51
52
    def check(self):
53
        """Return network socket metrics from proc file net/sockstat.
54
55
        Note: sockstat.TCP.mem is measured in pages, you can get the system page
56
        size from os.sysconf("SC_PAGESIZE")
57
58
        Note: FRAG: ip fragmentation
59
60
        :rtype: plumd.Result
61
        """
62
        result = plumd.Result("sockstat")
63
        # read and process - dat is a list of lines from fname
64
        dat = get_file_map_list(self.proc_file, 0, 0)
65
        ts = time.time()
66
        # each entry is a key: [metric, val, metric, val]
67
        for key, val in dat.items():
68
            if len(val) < 2:
69
                continue
70
            mstr = key[:-1]
71
            mnames = val[::2]
72
            # 1::2 - every second item
73
            mvals = deque([ int(i) for i in val[1::2] ])
74
            for mname in mnames:
75
                metric = "{0}.{1}".format(mstr, mname)
76
                result.add(plumd.Int(metric, mvals.popleft()))
77
        # also record configured tcp mem limits
78
        dat = get_file(self.fname_limits).split()
79
        if len(dat) == 3:
80
            # eg. for alerting/dashboard on pages allocated vs max values
81
            result.add(plumd.Int("TCP.mem_min", dat[0]))
82
            result.add(plumd.Int("TCP.mem_pressure", dat[1]))
83
            result.add(plumd.Int("TCP.mem_max", dat[1]))
84
        dat = get_file(self.fname_orph)
85
        result.add(plumd.Int("TCP.orphan_max", dat))
86
        return [result]
87