Skip to content

Commit 960efb2

Browse files
Added: snmptop utility. (#142)
* based on BaseTop interface * `--random` support * `--no-delta-mode` support * added to `tests_runnable` #143
1 parent 31ff0f7 commit 960efb2

File tree

7 files changed

+131
-2
lines changed

7 files changed

+131
-2
lines changed

netutils_linux_monitoring/layout.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ def make_table(header, align_map=None, rows=None):
1010
""" Wrapper for pretty table """
1111
table = PrettyTable()
1212
table.horizontal_char = table.vertical_char = table.junction_char = ' '
13-
table.field_names = header
13+
try:
14+
table.field_names = header
15+
except Exception as err:
16+
print_(header)
17+
raise err
1418
if align_map:
1519
for field, align in zip(header, align_map):
1620
table.align[field] = align

netutils_linux_monitoring/snmptop.py

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# coding=utf-8
2+
3+
from copy import deepcopy
4+
from random import randint
5+
6+
from six import iteritems
7+
8+
from netutils_linux_monitoring.base_top import BaseTop
9+
from netutils_linux_monitoring.layout import make_table
10+
11+
12+
class SnmpTop(BaseTop):
13+
""" Utility for monitoring IP/TCP/UDP/ICMP parts of network stack based on /proc/net/snmp values """
14+
15+
protos = ['IP', 'TCP', 'UDP', 'ICMP']
16+
17+
@staticmethod
18+
def make_parser(parser=None):
19+
""" :returns: parser with options for snmptop """
20+
if not parser:
21+
parser = BaseTop.make_parser()
22+
parser.add_argument('--snmp-file', default='/proc/net/snmp',
23+
help='Option for testing on MacOS purpose.')
24+
return parser
25+
26+
def __int(self, line):
27+
return [self.int(item) for item in line.strip().split()]
28+
29+
def eval(self):
30+
""" Evaluates difference between snmp metrics """
31+
self.diff = deepcopy(self.current)
32+
for proto, data in iteritems(self.diff):
33+
for i, metric in enumerate(data):
34+
_, value = metric
35+
if isinstance(value, int):
36+
if self.options.random:
37+
self.diff[proto][i][1] = randint(0, 1000)
38+
else:
39+
self.diff[proto][i][1] -= self.previous[proto][i][1]
40+
41+
@staticmethod
42+
def __listify(list_of_tuples):
43+
"""
44+
:param list_of_tuples: list[tuple]
45+
:return: list[list]
46+
"""
47+
return [list(tpl) for tpl in list_of_tuples]
48+
49+
def parse(self):
50+
""" :returns: dict[proto] = list[list[str(key), int(value)]] """
51+
with open(self.options.snmp_file) as file_fd:
52+
lines = [self.__int(line) for line in file_fd.readlines()]
53+
return {
54+
'IP': self.__listify(zip(lines[0][1:], lines[1][1:])),
55+
'ICMP': self.__listify(zip(lines[2][1:], lines[3][1:])),
56+
'TCP': self.__listify(zip(lines[6][1:], lines[7][1:])),
57+
'UDP': self.__listify(zip(lines[8][1:], lines[9][1:]))
58+
}
59+
60+
def __repr__(self):
61+
table = make_table(self.make_header(), self.make_align_map(), self.make_rows())
62+
return self.__repr_table__(table)
63+
64+
@staticmethod
65+
def make_header():
66+
""" :returns: header for prettytable output (provides unique invisible whitespace-headers)
67+
68+
6, 5, 4 spaces are for column blinking avoidance.
69+
"""
70+
return ['IP', ' ' * 6, 'TCP', ' ' * 5, 'UDP', ' ' * 4, 'ICMP', '']
71+
72+
def make_rows(self):
73+
""" :returns: rows for prettytable output (filled with empty values) """
74+
rows = []
75+
repr_source = self.repr_source()
76+
max_len = max(len(subdict) for subdict in repr_source.values())
77+
for index in range(max_len):
78+
row = list()
79+
for proto in self.protos:
80+
if index >= len(repr_source[proto]):
81+
row.extend(['', ''])
82+
continue
83+
row.extend([repr_source[proto][index][0], repr_source[proto][index][1]])
84+
rows.append(row)
85+
return rows
86+
87+
def make_align_map(self):
88+
""" :returns: align map for prettytable output (key <-, value -> for each proto """
89+
return ['l', 'r'] * len(self.protos)

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def read(*paths):
1616

1717
setuptools.setup(
1818
name='netutils-linux',
19-
version='2.2.10',
19+
version='2.3.0',
2020
author='Oleg Strizhechenko',
2121
author_email='[email protected]',
2222
license='MIT',

tests/proc_net_snmp/snmp1

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
2+
Ip: 1 64 22199703066 64 0 3991292426 3 0 18205118253 20899686159 1183 0 5 5 0 5 8 0 16
3+
Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
4+
Icmp: 17864682 762911 13469164 11533 0 53 7 4361700 21720 7 0 0 0 27650690 0 23265781 52 0 0 0 23150 4361700 0 7 0 0
5+
IcmpMsg: InType0 InType3 InType4 InType5 InType8 InType11 InType13 OutType0 OutType3 OutType8 OutType11 OutType14
6+
IcmpMsg: 21720 13469164 53 7 4361700 11533 7 4361700 23265781 23150 52 7
7+
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts
8+
Tcp: 1 200 120000 -1 1144887168 1265503546 23608568 26172378 77 17669927663 16338441124 133674663 167169 53028318
9+
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
10+
Udp: 494467706 14809371 76 319088 0 0
11+
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
12+
UdpLite: 0 0 0 0 0 0

tests/proc_net_snmp/snmp2

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
2+
Ip: 1 64 22199717960 64 0 3991292567 3 0 18205133002 20899699894 1183 0 5 5 0 5 8 0 16
3+
Icmp: InMsgs InErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
4+
Icmp: 17864706 762912 13469188 11533 0 53 7 4361700 21720 7 0 0 0 27650753 0 23265844 52 0 0 0 23150 4361700 0 7 0 0
5+
IcmpMsg: InType0 InType3 InType4 InType5 InType8 InType11 InType13 OutType0 OutType3 OutType8 OutType11 OutType14
6+
IcmpMsg: 21720 13469188 53 7 4361700 11533 7 4361700 23265844 23150 52 7
7+
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts
8+
Tcp: 1 200 120000 -1 1144887961 1265504683 23608597 26172379 79 17669942271 16338454400 133674769 167169 53028393
9+
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
10+
Udp: 494467738 14809443 76 319088 0 0
11+
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors
12+
UdpLite: 0 0 0 0 0 0

tests/utils_runnable

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ softirq="./tests/softirqs/i7/softirqs1"
66
irq="./tests/interrupts/singlequeue_8cpu/interrupts_short"
77
soft_net_stat="./tests/softnet_stat/softnet_stat1"
88
devices="eth1,eth2,eth3"
9+
snmp="./tests/proc_net_snmp/snmp1"
910

1011
network-top --no-clear -n 1 --random \
1112
--softirqs-file="$softirq" \
@@ -16,6 +17,7 @@ link-rate --no-clear -n 1 --random --devices="$devices"
1617
irqtop --no-clear -n 1 --random --interrupts-file="$irq"
1718
softirq-top --no-clear -n 1 --random --softirqs-file="$softirq"
1819
softnet-stat-top --no-clear -n 1 --random --softnet-stat-file="$soft_net_stat"
20+
snmptop --no-clear -n 1 --random --snmp-file="$snmp"
1921
autorps --help
2022
autoxps --help
2123
rss-ladder --help

utils/snmptop

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env python
2+
3+
# coding: utf-8
4+
5+
from netutils_linux_monitoring.snmptop import SnmpTop
6+
7+
if __name__ == '__main__':
8+
top = SnmpTop()
9+
top.options = top.make_parser().parse_args()
10+
top.run()

0 commit comments

Comments
 (0)