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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
#!/router/bin/python-2.4.3
import time,os, sys, string
from os.path import exists
from os import system, remove, chdir
import re
import time
import random
import copy
import telnetlib
import datetime
import collections
from trex_perf import TrexRunException
import random
import time
class RouterIOException(Exception):
def __init__ (self, reason):
# generate the error message
#self.message = "\nSummary of error:\n\n %s\n" % (reason)
self.message = reason
def __str__(self):
return self.message
# basic router class
class Router:
def __init__ (self, host, port, password, str_wait = "#"):
self.host = host
self.port = port;
self.pr = str_wait;
self.password = password
self.to = 60
self.cpu_util_histo = []
# private function - command send
def _command (self, command, match = None, timeout = None):
to = timeout if (timeout != None) else self.to
m = match if (match != None) else [self.pr]
if not isinstance(m, list):
m = [m]
total_to = 0
while True:
self.tn.write(command + "\n")
ret = self.tn.expect(m, timeout = 2)
total_to += 2
if ret[0] != -1:
result = {}
result['match_index'] = ret[0]
result['output'] = ret[2]
return (result)
if total_to >= self.to:
raise RouterIOException("Failed to process command to router %s" % command)
# connect to router by telnet
def connect (self):
# create telnet session
self.tn = telnetlib.Telnet ()
try:
self.tn.open(self.host, self.port)
except IOError:
raise RouterIOException("Failed To Connect To Router interface at '%s' : '%s'" % (self.host, self.port))
# get a ready console and decides if you need password
ret = self._command("", ["Password", ">", "#"])
if ret['match_index'] == 0:
self._command(self.password, [">", "#"])
# can't hurt to call enable even if on enable
ret = self._command("enable 15", ["Password", "#"])
if (ret['match_index'] == 0):
self._command(self.password, "#")
self._command("terminal length 0")
def close (self):
self.tn.close ()
self.tn = None
# implemented through derived classes
def sample_cpu (self):
raise Exception("abstract method called")
def get_last_cpu_util (self):
if not self.cpu_util_histo:
return (0)
else:
return self.cpu_util_histo[len(self.cpu_util_histo) - 1]
def get_cpu_util_histo (self):
return self.cpu_util_histo
def get_filtered_cpu_util_histo (self):
trim_start = int(0.15 * len(self.cpu_util_histo))
filtered = self.cpu_util_histo[trim_start:]
if not filtered:
return [0]
m = collections.Counter(filtered).most_common(n = 1)[0][0]
#m = max(self.cpu_util_histo)
filtered = [x for x in filtered if (x > (0.9*m))]
return filtered
def clear_sampling_stats (self):
self.cpu_util_histo = []
# add a sample to the database
def sample_stats (self):
# sample CPU util
cpu_util = self.sample_cpu()
self.cpu_util_histo.append(cpu_util)
def get_stats (self):
stats = {}
filtered_cpu_util = self.get_filtered_cpu_util_histo()
if not filtered_cpu_util:
stats['cpu_util'] = 0
else:
stats['cpu_util'] = sum(filtered_cpu_util)/len(filtered_cpu_util)
stats['cpu_histo'] = self.get_cpu_util_histo()
return stats
class ASR1k(Router):
def __init__ (self, host, password, port, str_wait = "#"):
Router.__init__(self, host, password, port, str_wait)
def sample_cpu (self):
cpu_show_cmd = "show platform hardware qfp active datapath utilization | inc Load"
output = self._command(cpu_show_cmd)['output']
lines = output.split('\n');
cpu_util = -1.0
# search for the line
for l in lines:
m = re.match("\W*Processing: Load\D*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\D*", l)
if m:
cpu_util = float(m.group(1))
if (cpu_util == -1.0):
raise Exception("cannot determine CPU util. for asr1k")
return cpu_util
class ISR(Router):
def __init__ (self, host, password, port, str_wait = "#"):
Router.__init__(self, host, password, port, str_wait)
def sample_cpu (self):
cpu_show_cmd = "show processes cpu sorted | inc CPU utilization"
output = self._command(cpu_show_cmd)['output']
lines = output.split('\n');
cpu_util = -1.0
# search for the line
for l in lines:
m = re.match("\W*CPU utilization for five seconds: (\d+)%/(\d+)%", l)
if m:
max_cpu_util = float(m.group(1))
min_cpu_util = float(m.group(2))
cpu_util = (min_cpu_util + max_cpu_util)/2
if (cpu_util == -1.0):
raise Exception("cannot determine CPU util. for ISR")
return cpu_util
if __name__ == "__main__":
#router = ASR1k("pqemb19ts", "cisco", port=2052)
router = ISR("10.56.198.7", "lab")
router.connect()
for i in range(1, 10):
router.sample_stats()
time.sleep(1)
|