specify interface option for monitoring command
[osm/vim-emu.git] / src / emuvim / dcemulator / monitoring.py
1 __author__ = 'Administrator'
2
3 import urllib2
4 import logging
5 from mininet.node import OVSSwitch
6 import ast
7 import time
8 logging.basicConfig(level=logging.INFO)
9
10 """
11 class to read openflow stats from the Ryu controller of the DCNEtwork
12 """
13
14 class DCNetworkMonitor():
15 def __init__(self, net):
16 self.net = net
17 # link to REST_API
18 self.ip = '0.0.0.0'
19 self.port = '8080'
20 self.REST_api = 'http://{0}:{1}'.format(self.ip,self.port)
21
22 self.previous_measurement = 0
23 self.previous_monitor_time = 0
24
25 def get_rate(self, vnf_name, direction='tx', metric='packets'):
26 # check if port is specified (vnf:port)
27 try:
28 vnf_interface = vnf_name.split(':')[1]
29 except:
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
35
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']
39
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
48
49 mon_port = link_dict[link]['dst_port']
50 break
51
52 try:
53 # default port direction to monitor
54 if direction is None:
55 direction = 'tx'
56
57 vnf_switch = self.net.DCNetwork_graph.neighbors(str(vnf_name))
58
59 if len(vnf_switch) > 1:
60 logging.info("vnf: {0} has multiple ports".format(vnf_name))
61 return
62 elif len(vnf_switch) == 0:
63 logging.info("vnf: {0} is not connected".format(vnf_name))
64 return
65 else:
66 vnf_switch = vnf_switch[0]
67 next_node = self.net.getNodeByName(vnf_switch)
68
69 if not isinstance( next_node, OVSSwitch ):
70 logging.info("vnf: {0} is not connected to switch".format(vnf_name))
71 return
72
73
74 switch_dpid = x = int(str(next_node.dpid),16)
75
76 # TODO get metric name from arg
77 key = '{0}_{1}'.format(direction, metric)
78
79
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]
86
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
91 time.sleep(1)
92 byte_rate = self.get_rate(vnf_name,direction)
93 return byte_rate
94 else:
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))
98 #return byte_rate
99
100 self.previous_measurement = this_measurement
101 self.previous_monitor_time = port_uptime
102 return byte_rate
103
104 return ret
105
106 except Exception as ex:
107 logging.exception("get_txrate error.")
108 return ex.message
109
110
111
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()
116 return ret