-
Notifications
You must be signed in to change notification settings - Fork 74
/
softnet_stat.py
91 lines (73 loc) · 3.33 KB
/
softnet_stat.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# coding=utf-8
from random import randint
from netutils_linux_monitoring.base_top import BaseTop
from netutils_linux_monitoring.layout import make_table
class SoftnetStat(object):
""" Representation for 1 CPU data in /proc/net/softnet_stat """
cpu = None
total = None
dropped = None
time_squeeze = None
cpu_collision = None
received_rps = None
attributes = ['cpu', 'total', 'dropped', 'time_squeeze', 'cpu_collision', 'received_rps']
def __init__(self, random=False):
self.random = random
def parse_string(self, row, cpu):
""" Initialize SoftnetStat by string from /proc/net/softnet_stat """
row = [int('0x' + x, 16) for x in row.strip().split()]
self.total, self.dropped, self.time_squeeze = row[0:3]
self.cpu_collision = row[6]
self.received_rps = row[7]
self.cpu = cpu
return self
def parse_list(self, data):
""" Initialize SoftnetStat by list of integers """
self.cpu, self.total, self.dropped, self.time_squeeze, self.cpu_collision, self.received_rps = data
return self
def sub(self, attr, other, _min, _max):
return randint(_min, _max) if self.random else getattr(self, attr) - getattr(other, attr)
def __sub__(self, other):
return SoftnetStat().parse_list([
self.cpu,
self.sub('total', other, 1, 10000),
self.sub('dropped', other, 0, 1),
self.sub('time_squeeze', other, 0, 10),
self.sub('cpu_collision', other, 0, 0),
self.sub('received_rps', other, 0, 5),
])
def __eq__(self, other):
return all([getattr(self, attr) == getattr(other, attr) for attr in self.attributes])
class SoftnetStatTop(BaseTop):
""" Utility for monitoring packets processing/errors distribution per CPU """
file_arg, file_value = '--softnet-stat-file', '/proc/net/softnet_stat'
align = ['l'] + ['r'] * 5
total_warning, total_error = 300000, 900000
dropped_warning = dropped_error = 1
time_squeeze_warning, time_squeeze_error = 1, 300
cpu_collision_warning, cpu_collision_error = 1, 1000
def __init__(self, topology=None):
BaseTop.default_init(self, topology)
def post_optparse(self):
BaseTop.default_post_optparse(self)
def parse(self):
with open(self.options.softnet_stat_file) as softnet_stat:
data = enumerate(softnet_stat.read().strip().split('\n'))
return [SoftnetStat(self.options.random).parse_string(row, cpu) for cpu, row in data]
def eval(self):
self.diff = [data - self.previous[cpu] for cpu, data in enumerate(self.current)]
def __repr__(self):
table = make_table(self.make_header(), self.align, list(self.make_rows()))
return self.__repr_table__(table)
@staticmethod
def make_header():
return ['CPU', 'total', 'dropped', 'time_squeeze', 'cpu_collision', 'received_rps']
def make_rows(self):
return [[
self.color.wrap('CPU{0}'.format(stat.cpu), self.color.colorize_cpu(stat.cpu)),
self.color.colorize(stat.total, 300000, 900000),
self.color.colorize(stat.dropped, 1, 1),
self.color.colorize(stat.time_squeeze, 1, 300),
self.color.colorize(stat.cpu_collision, 1, 1000),
stat.received_rps
] for stat in self.repr_source()]