1 __author__
= 'Administrator'
5 from mininet
.node
import OVSSwitch
8 logging
.basicConfig(level
=logging
.INFO
)
11 class to read openflow stats from the Ryu controller of the DCNEtwork
14 class DCNetworkMonitor():
15 def __init__(self
, net
):
20 self
.REST_api
= 'http://{0}:{1}'.format(self
.ip
,self
.port
)
22 self
.previous_measurement
= 0
23 self
.previous_monitor_time
= 0
25 self
.metric_key
= None
28 # first set some parameters, before measurement can start
29 def setup_rate_measurement(self
, vnf_name
, vnf_interface
=None, direction
='tx', metric
='packets'):
30 # check if port is specified (vnf:port)
31 if vnf_interface
is None:
32 # take first interface by default
33 connected_sw
= self
.net
.DCNetwork_graph
.neighbors(vnf_name
)[0]
34 link_dict
= self
.net
.DCNetwork_graph
[vnf_name
][connected_sw
]
35 vnf_interface
= link_dict
[0]['src_port_id']
37 for connected_sw
in self
.net
.DCNetwork_graph
.neighbors(vnf_name
):
38 link_dict
= self
.net
.DCNetwork_graph
[vnf_name
][connected_sw
]
39 for link
in link_dict
:
40 # logging.info("{0},{1}".format(link_dict[link],vnf_interface))
41 if link_dict
[link
]['src_port_id'] == vnf_interface
:
42 # found the right link and connected switch
43 # logging.info("{0},{1}".format(link_dict[link]['src_port_id'], vnf_source_interface))
44 self
.mon_port
= link_dict
[link
]['dst_port']
48 # default port direction to monitor
54 vnf_switch
= self
.net
.DCNetwork_graph
.neighbors(str(vnf_name
))
56 if len(vnf_switch
) > 1:
57 logging
.info("vnf: {0} has multiple ports".format(vnf_name
))
59 elif len(vnf_switch
) == 0:
60 logging
.info("vnf: {0} is not connected".format(vnf_name
))
63 vnf_switch
= vnf_switch
[0]
64 next_node
= self
.net
.getNodeByName(vnf_switch
)
66 if not isinstance(next_node
, OVSSwitch
):
67 logging
.info("vnf: {0} is not connected to switch".format(vnf_name
))
70 self
.previous_measurement
= 0
71 self
.previous_monitor_time
= 0
73 #self.switch_dpid = x = int(str(next_node.dpid), 16)
74 self
.switch_dpid
= int(str(next_node
.dpid
), 16)
75 self
.metric_key
= '{0}_{1}'.format(direction
, metric
)
77 except Exception as ex
:
78 logging
.exception("get_txrate error.")
82 # call this function repeatedly for streaming measurements
83 def get_rate(self
, vnf_name
, vnf_interface
=None, direction
='tx', metric
='packets'):
87 ret
= self
.REST_cmd('stats/port', self
.switch_dpid
)
88 port_stat_dict
= ast
.literal_eval(ret
)
89 for port_stat
in port_stat_dict
[str(self
.switch_dpid
)]:
90 if port_stat
['port_no'] == self
.mon_port
:
91 port_uptime
= port_stat
['duration_sec'] + port_stat
['duration_nsec'] * 10 ** (-9)
92 this_measurement
= port_stat
[key
]
94 if self
.previous_monitor_time
<= 0 or self
.previous_monitor_time
>= port_uptime
:
95 self
.previous_measurement
= port_stat
[key
]
96 self
.previous_monitor_time
= port_uptime
97 # do first measurement
99 byte_rate
= self
.get_rate(vnf_name
, vnf_interface
, direction
, metric
)
102 time_delta
= (port_uptime
- self
.previous_monitor_time
)
103 byte_rate
= (this_measurement
- self
.previous_measurement
) / float(time_delta
)
104 #logging.info('uptime:{2} delta:{0} rate:{1}'.format(time_delta,byte_rate,port_uptime))
106 self
.previous_measurement
= this_measurement
107 self
.previous_monitor_time
= port_uptime
112 def REST_cmd(self
, prefix
, dpid
):
113 url
= self
.REST_api
+ '/' + str(prefix
) + '/' + str(dpid
)
114 req
= urllib2
.Request(url
)
115 ret
= urllib2
.urlopen(req
).read()