SockStat   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 71
Duplicated Lines 25.35 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 7
c 3
b 0
f 1
dl 18
loc 71
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A poll() 0 6 1
B check() 0 37 5
A __init__() 16 18 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
# -*- coding: utf-8 -*-
2
"""Socket stat reader for /proc on Linux."""
3
4
import time
0 ignored issues
show
Unused Code introduced by
The import time seems to be unused.
Loading history...
5
from collections import deque
6
7
import plumd
8
from plumd.util import Differential
9
from plumd.util import get_file_map_list, get_file, Filter
10
11
__author__ = 'Kenny Freeman'
12
__email__ = '[email protected]'
13
__license__ = "ISCL"
14
__docformat__ = 'reStructuredText'
15
16
17
class SockStat(plumd.Reader):
18
    """Plugin to measure various kernel metrics from /proc."""
19
20
    defaults = {
21
        'poll.interval': 10,
22
        'proc_path': '/proc'
23 View Code Duplication
    }
24
25
    def __init__(self, log, config):
26
        """Plugin to measure various kernel metrics from /proc.
27
28
        :param log: A logger
29
        :type log: logging.RootLogger
30
        :param config: a plumd.config.Conf configuration helper instance.
31
        :type config: plumd.config.Conf
32
        """
33
        super(SockStat, self).__init__(log, config)
34
        self.config.defaults(SockStat.defaults)
35
        self.calc = Differential()
36
        proc_path = config.get('proc_path')
37
        self.proc_file = "{0}/net/sockstat".format(proc_path)
38
        # sys/net/ipv4/tcp_mem format: min, pressure, max
39
        self.fname_limits = "{0}/sys/net/ipv4/tcp_mem".format(proc_path)
40
        # orphan limit: /proc/sys/net/ipv4/tcp_max_orphans
41
        self.fname_orph = "{0}/sys/net/ipv4/tcp_max_orphans".format(proc_path)
42
        self.filter = Filter()
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
    def check(self):
52
        """Return network socket metrics from proc file net/sockstat.
53
54
        Note: sockstat.TCP.mem is measured in pages, you can get the system page
55
        size from os.sysconf("SC_PAGESIZE")
56
57
        Note: FRAG: ip fragmentation
58
59
        :rtype: plumd.Result
60
        """
61
        result = plumd.Result("sockstat")
62
63
        # read and process - dat is a list of lines from fname
64
        dat = get_file_map_list(self.proc_file, 0, 0)
65
66
        # each entry is a key: [metric, val, metric, val]
67
        for key, val in dat.items():
68
            mstr = key[:-1]
69
            mnames = val[::2]
70
            # 1::2 - every second item
71
            mvals = deque([int(i) for i in val[1::2]])
72
            for mname in mnames:
73
                metric = "{0}.{1}".format(mstr, mname)
74
                result.add(plumd.Int(metric, mvals.popleft()))
75
76
        # also record configured tcp mem limits
77
        dat = get_file(self.fname_limits).split()
78
        if len(dat) == 3:
79
            # eg. for alerting/dashboard on pages allocated vs max values
80
            result.add(plumd.Int("TCP.mem_min", dat[0]))
81
            result.add(plumd.Int("TCP.mem_pressure", dat[1]))
82
            result.add(plumd.Int("TCP.mem_max", dat[1]))
83
84
        # and max orphans
85
        dat = get_file(self.fname_orph)
86
        result.add(plumd.Int("TCP.orphan_max", dat))
87
        return [result]
88