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

SockStat.check()   B

Complexity

Conditions 6

Size

Total Lines 34

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