22import re
33import time
44import copy
5+ import string
56
67PARAMS = {}
78
1011 'data' : {}
1112}
1213
13-
14- tcpext_file = "/proc/net/netstat"
15- snmp_file = "/proc/net/snmp"
14+ stats_files = [ "/proc/net/netstat" , "/proc/net/snmp" ]
1615
1716LAST_METRICS = copy .deepcopy (METRICS )
1817METRICS_CACHE_MAX = 5
1918
2019stats_pos = {}
2120
22- stats_pos ['tcpext' ] = {
23- 'syncookiessent' : 1 ,
24- 'syncookiesrecv' : 2 ,
25- 'syncookiesfailed' : 3 ,
26- 'embryonicrsts' : 4 ,
27- 'prunecalled' : 5 ,
28- 'rcvpruned' : 6 ,
29- 'ofopruned' : 7 ,
30- 'outofwindowicmps' : 8 ,
31- 'lockdroppedicmps' : 9 ,
32- 'arpfilter' : 10 ,
33- 'tw' : 11 ,
34- 'twrecycled' : 12 ,
35- 'twkilled' : 13 ,
36- 'pawspassive' : 14 ,
37- 'pawsactive' : 15 ,
38- 'pawsestab' : 16 ,
39- 'delayedacks' : 17 ,
40- 'delayedacklocked' : 18 ,
41- 'delayedacklost' : 19 ,
42- 'listenoverflows' : 20 ,
43- 'listendrops' : 21 ,
44- 'tcpprequeued' : 22 ,
45- 'tcpdirectcopyfrombacklog' : 23 ,
46- 'tcpdirectcopyfromprequeue' : 24 ,
47- 'tcpprequeuedropped' : 25 ,
48- 'tcphphits' : 26 ,
49- 'tcphphitstouser' : 27 ,
50- 'tcppureacks' : 28 ,
51- 'tcphpacks' : 29 ,
52- 'tcprenorecovery' : 30 ,
53- 'tcpsackrecovery' : 31 ,
54- 'tcpsackreneging' : 32 ,
55- 'tcpfackreorder' : 33 ,
56- 'tcpsackreorder' : 34 ,
57- 'tcprenoreorder' : 35 ,
58- 'tcptsreorder' : 36 ,
59- 'tcpfullundo' : 37 ,
60- 'tcppartialundo' : 38 ,
61- 'tcpdsackundo' : 39 ,
62- 'tcplossundo' : 40 ,
63- 'tcploss' : 41 ,
64- 'tcplostretransmit' : 42 ,
65- 'tcprenofailures' : 43 ,
66- 'tcpsackfailures' : 44 ,
67- 'tcplossfailures' : 45 ,
68- 'tcpfastretrans' : 46 ,
69- 'tcpforwardretrans' : 47 ,
70- 'tcpslowstartretrans' : 48 ,
71- 'tcptimeouts' : 49 ,
72- 'tcprenorecoveryfail' : 50 ,
73- 'tcpsackrecoveryfail' : 51 ,
74- 'tcpschedulerfailed' : 52 ,
75- 'tcprcvcollapsed' : 53 ,
76- 'tcpdsackoldsent' : 54 ,
77- 'tcpdsackofosent' : 55 ,
78- 'tcpdsackrecv' : 56 ,
79- 'tcpdsackoforecv' : 57 ,
80- 'tcpabortonsyn' : 58 ,
81- 'tcpabortondata' : 59 ,
82- 'tcpabortonclose' : 60 ,
83- 'tcpabortonmemory' : 61 ,
84- 'tcpabortontimeout' : 62 ,
85- 'tcpabortonlinger' : 63 ,
86- 'tcpabortfailed' : 64 ,
87- 'tcpmemorypressures' : 65 ,
88- 'tcpsackdiscard' : 66 ,
89- 'tcpdsackignoredold' : 67 ,
90- 'tcpdsackignorednoundo' : 68 ,
91- 'tcpspuriousrtos' : 69 ,
92- 'tcpmd5notfound' : 70 ,
93- 'tcpmd5unexpected' : 71 ,
94- 'tcpsackshifted' : 72 ,
95- 'tcpsackmerged' : 73 ,
96- 'tcpsackshiftfallback' : 74 ,
97- 'tcpbacklogdrop' : 75 ,
98- 'tcpminttldrop' : 76 ,
99- 'tcpdeferacceptdrop' : 77
100- }
101-
102- stats_pos ['ip' ] = {
103- 'inreceives' : 3 ,
104- 'inhdrerrors' : 4 ,
105- 'inaddrerrors' : 5 ,
106- 'forwdatagrams' : 6 ,
107- 'inunknownprotos' : 7 ,
108- 'indiscards' : 8 ,
109- 'indelivers' : 9 ,
110- 'outrequests' : 10 ,
111- 'outdiscards' : 11 ,
112- 'outnoroutes' : 12 ,
113- 'reasmtimeout' : 13 ,
114- 'reasmreqds' : 14 ,
115- 'reasmoks' : 15 ,
116- 'reasmfails' : 16 ,
117- 'fragoks' : 17 ,
118- 'fragfails' : 18 ,
119- 'fragcreates' : 19
120- }
121-
122- stats_pos ['tcp' ] = {
123- 'activeopens' : 5 ,
124- 'passiveopens' : 6 ,
125- 'attemptfails' : 7 ,
126- 'estabresets' : 8 ,
127- 'currestab' : 9 ,
128- 'insegs' : 10 ,
129- 'outsegs' : 11 ,
130- 'retranssegs' : 12 ,
131- 'inerrs' : 13 ,
132- 'outrsts' : 14
133- }
134-
135- stats_pos ['udp' ] = {
136- 'indatagrams' : 1 ,
137- 'noports' : 2 ,
138- 'inerrors' : 3 ,
139- 'outdatagrams' : 4 ,
140- 'rcvbuferrors' : 5 ,
141- 'sndbuferrors' : 6 ,
142- }
143-
144- stats_pos ['icmp' ] = {
145- 'inmsgs' : 1 ,
146- 'inerrors' : 2 ,
147- 'indestunreachs' : 3 ,
148- 'intimeexcds' : 4 ,
149- 'inparmprobs' : 5 ,
150- 'insrcquenchs' : 6 ,
151- 'inredirects' : 7 ,
152- 'inechos' : 8 ,
153- 'inechoreps' : 9 ,
154- 'intimestamps' : 10 ,
155- 'intimestampreps' : 11 ,
156- 'inaddrmasks' : 12 ,
157- 'inaddrmaskreps' : 13 ,
158- 'outmsgs' : 14 ,
159- 'outerrors' : 15 ,
160- 'outdestunreachs' : 16 ,
161- 'outtimeexcds' : 17 ,
162- 'outparmprobs' : 18 ,
163- 'outsrcquenchs' : 19 ,
164- 'outredirects' : 20 ,
165- 'outechos' : 21 ,
166- 'outechoreps' : 22 ,
167- 'outtimestamps' : 23 ,
168- 'outtimestampreps' : 24 ,
169- 'outaddrmasks' : 25 ,
170- 'outaddrmaskreps' : 26
171- }
172-
17321def get_metrics ():
17422 """Return all metrics"""
17523
17624 global METRICS , LAST_METRICS
17725
17826 if (time .time () - METRICS ['time' ]) > METRICS_CACHE_MAX :
17927
180- try :
181- file = open (tcpext_file , 'r' )
182-
183- except IOError :
184- return 0
28+ new_metrics = {}
18529
186- # convert to dict
187- metrics = {}
188- for line in file :
189- if re .match ("TcpExt: [0-9]" , line ):
190- metrics = re .split ("\s+" , line )
191-
192- file .close ()
30+ for file in stats_files :
31+ try :
32+ file = open (file , 'r' )
33+
34+ except IOError :
35+ return 0
36+
37+ # convert to dict
38+ metrics = {}
39+ for line in file :
40+ if re .match ("(.*): [0-9]" , line ):
41+ count = 0
42+ metrics = re .split ("\s+" , line )
43+ metric_group = metrics [0 ].replace (":" , "" ).lower ()
44+ new_metrics [metric_group ] = dict ()
45+ for value in metrics :
46+ # Skip first
47+ if count > 0 and value >= 0 and count in stats_pos [metric_group ]:
48+ metric_name = stats_pos [metric_group ][count ]
49+ new_metrics [metric_group ][metric_name ] = value
50+ count += 1
51+
52+ file .close ()
19353
19454 # update cache
19555 LAST_METRICS = copy .deepcopy (METRICS )
19656 METRICS = {
19757 'time' : time .time (),
198- 'tcpext ' : metrics
58+ 'data ' : new_metrics
19959 }
20060
201-
202- ######################################################################
203- # Let's get stats from /proc/net/snmp
204- ######################################################################
205- try :
206- file = open (snmp_file , 'r' )
207-
208- except IOError :
209- return 0
210-
211- for line in file :
212- if re .match ("Udp: [0-9]" , line ):
213- METRICS ['udp' ] = re .split ("\s+" , line )
214- if re .match ("Ip: [0-9]" , line ):
215- METRICS ['ip' ] = re .split ("\s+" , line )
216- if re .match ("Tcp: [0-9]" , line ):
217- METRICS ['tcp' ] = re .split ("\s+" , line )
218-
219-
220- file .close ()
221-
22261 return [METRICS , LAST_METRICS ]
22362
22463
@@ -245,10 +84,10 @@ def get_delta(name):
24584
24685 parts = name .split ("_" )
24786 group = parts [0 ]
248- index = stats_pos [ group ][ parts [1 ]]
87+ metric = "_" . join ( parts [1 :])
24988
25089 try :
251- delta = (float (curr_metrics [group ][index ]) - float (last_metrics [group ][index ])) / (curr_metrics ['time' ] - last_metrics ['time' ])
90+ delta = (float (curr_metrics ['data' ][ group ][metric ]) - float (last_metrics ['data' ][ group ][metric ])) / (curr_metrics ['time' ] - last_metrics ['time' ])
25291 if delta < 0 :
25392 print name + " is less 0"
25493 delta = 0
@@ -263,12 +102,8 @@ def get_tcploss_percentage(name):
263102 # get metrics
264103 [curr_metrics , last_metrics ] = get_metrics ()
265104
266- index_outsegs = stats_pos ["tcp" ]["outsegs" ]
267- index_insegs = stats_pos ["tcp" ]["insegs" ]
268- index_loss = stats_pos ["tcpext" ]["tcploss" ]
269-
270105 try :
271- pct = 100 * (float (curr_metrics ['tcpext' ][index_loss ]) - float (last_metrics ['tcpext' ][index_loss ])) / (float (curr_metrics ['tcp' ][index_outsegs ]) + float (curr_metrics ['tcp' ][index_insegs ]) - float (last_metrics ['tcp' ][index_insegs ]) - float (last_metrics ['tcp' ][index_outsegs ]))
106+ pct = 100 * (float (curr_metrics ['data' ][ ' tcpext' ]["tcploss" ]) - float (last_metrics ["data" ][ 'tcpext' ]["tcploss" ])) / (float (curr_metrics ['data' ][ ' tcp' ]['outsegs' ]) + float (curr_metrics ['data' ][ ' tcp' ]['insegs' ]) - float (last_metrics ['data' ][ ' tcp' ]['insegs' ]) - float (last_metrics ['data' ][ ' tcp' ]['outsegs' ]))
272107 if pct < 0 :
273108 print name + " is less 0"
274109 pct = 0
@@ -282,12 +117,8 @@ def get_retrans_percentage(name):
282117 # get metrics
283118 [curr_metrics , last_metrics ] = get_metrics ()
284119
285- index_outsegs = stats_pos ["tcp" ]["outsegs" ]
286- index_insegs = stats_pos ["tcp" ]["insegs" ]
287- index_retrans = stats_pos ["tcp" ]["retranssegs" ]
288-
289120 try :
290- pct = 100 * (float (curr_metrics ['tcp' ][index_retrans ]) - float (last_metrics ['tcp' ][index_retrans ])) / (float (curr_metrics ['tcp' ][index_outsegs ]) + float (curr_metrics ['tcp' ][index_insegs ]) - float (last_metrics ['tcp' ][index_insegs ]) - float (last_metrics ['tcp' ][index_outsegs ]))
121+ pct = 100 * (float (curr_metrics ['data' ][ ' tcp' ]["retranssegs" ]) - float (last_metrics ['data' ][ ' tcp' ]["retranssegs" ])) / (float (curr_metrics ['data' ][ ' tcp' ]['outsegs' ]) + float (curr_metrics ['data' ][ ' tcp' ]['insegs' ]) - float (last_metrics ['data' ][ ' tcp' ]['insegs' ]) - float (last_metrics ['data' ][ ' tcp' ]['outsegs' ]))
291122 if pct < 0 :
292123 print name + " is less 0"
293124 pct = 0
@@ -320,11 +151,40 @@ def metric_init(params):
320151 'groups' : 'XXX' ,
321152 }
322153
154+ ####################################################################################
155+ # Let's figure out what metrics are available
156+ #
157+ # Read /proc/net/netstat
158+ ####################################################################################
159+ for file in stats_files :
160+ try :
161+ file = open (file , 'r' )
162+
163+ except IOError :
164+ return 0
165+
166+ # Find mapping
167+ for line in file :
168+ # Lines with
169+ if not re .match ("(.*): [0-9]" , line ):
170+ count = 0
171+ mapping = re .split ("\s+" , line )
172+ metric_group = mapping [0 ].replace (":" , "" ).lower ()
173+ stats_pos [metric_group ] = dict ()
174+ for metric in mapping :
175+ # Skip first
176+ if count > 0 and metric != "" :
177+ lowercase_metric = metric .lower ()
178+ stats_pos [metric_group ][count ] = lowercase_metric
179+ count += 1
180+
181+ file .close ()
182+
323183 for group in stats_pos :
324184 for item in stats_pos [group ]:
325185 descriptors .append (create_desc (Desc_Skel , {
326- "name" : group + "_" + item ,
327- "description" : item ,
186+ "name" : group + "_" + stats_pos [ group ][ item ] ,
187+ "description" : stats_pos [ group ][ item ] ,
328188 'groups' : group
329189 }))
330190
0 commit comments