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 def get_rate(self
, vnf_name
, direction
='tx', metric
='packets'):
26 # check if port is specified (vnf:port)
28 vnf_interface
= vnf_name
.split(':')[1]
30 # take first interface by default
31 connected_sw
= self
.net
.DCNetwork_graph
.neighbors(vnf_name
)[0]
32 link_dict
= self
.net
.DCNetwork_graph
[vnf_name
][connected_sw
]
33 vnf_interface
= link_dict
[0]['src_port_id']
34 # vnf_source_interface = 0
36 vnf_name
= vnf_name
.split(':')[0]
37 # take into account that this is a MultiGraph
38 #mon_port = self.net.DCNetwork_graph[vnf_name][connected_sw][0]['dst_port']
40 for connected_sw
in self
.net
.DCNetwork_graph
.neighbors(vnf_name
):
41 link_dict
= self
.net
.DCNetwork_graph
[vnf_name
][connected_sw
]
42 for link
in link_dict
:
43 # logging.info("{0},{1}".format(link_dict[link],vnf_source_interface))
44 if link_dict
[link
]['src_port_id'] == vnf_interface
:
45 # found the right link and connected switch
46 # logging.info("{0},{1}".format(link_dict[link]['src_port_id'], vnf_source_interface))
47 #src_sw = connected_sw
49 mon_port
= link_dict
[link
]['dst_port']
53 # default port direction to monitor
57 vnf_switch
= self
.net
.DCNetwork_graph
.neighbors(str(vnf_name
))
59 if len(vnf_switch
) > 1:
60 logging
.info("vnf: {0} has multiple ports".format(vnf_name
))
62 elif len(vnf_switch
) == 0:
63 logging
.info("vnf: {0} is not connected".format(vnf_name
))
66 vnf_switch
= vnf_switch
[0]
67 next_node
= self
.net
.getNodeByName(vnf_switch
)
69 if not isinstance( next_node
, OVSSwitch
):
70 logging
.info("vnf: {0} is not connected to switch".format(vnf_name
))
74 switch_dpid
= x
= int(str(next_node
.dpid
),16)
76 # TODO get metric name from arg
77 key
= '{0}_{1}'.format(direction
, metric
)
80 ret
= self
.REST_cmd('stats/port', switch_dpid
)
81 port_stat_dict
= ast
.literal_eval(ret
)
82 for port_stat
in port_stat_dict
[str(switch_dpid
)]:
83 if port_stat
['port_no'] == mon_port
:
84 port_uptime
= port_stat
['duration_sec'] + port_stat
['duration_nsec'] * 10 ** (-9)
85 this_measurement
= port_stat
[key
]
87 if self
.previous_monitor_time
<= 0 or self
.previous_monitor_time
>= port_uptime
:
88 self
.previous_measurement
= port_stat
[key
]
89 self
.previous_monitor_time
= port_uptime
90 # do first measurement
92 byte_rate
= self
.get_rate(vnf_name
,direction
)
95 time_delta
= (port_uptime
- self
.previous_monitor_time
)
96 byte_rate
= (this_measurement
- self
.previous_measurement
) / float(time_delta
)
97 #logging.info('uptime:{2} delta:{0} rate:{1}'.format(time_delta,byte_rate,port_uptime))
100 self
.previous_measurement
= this_measurement
101 self
.previous_monitor_time
= port_uptime
106 except Exception as ex
:
107 logging
.exception("get_txrate error.")
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()