7 Class for keeping track of host statistics
12 TYPE_AL = 1 # AffinityLink
15 def __init__(self, stat_type, **kwargs):
16 self.stat_type = stat_type
17 if stat_type == Stats.TYPE_HOST:
18 self.src = kwargs['src']
19 self.dst = kwargs['dst']
20 self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/hoststats/"
21 elif stat_type == Stats.TYPE_AL:
22 self.al = kwargs['al']
23 self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/affinitylinkstats/"
24 elif stat_type == Stats.TYPE_PREFIX:
25 self.subnet = kwargs['subnet']
26 self.url_prefix = "http://localhost:8080/affinity/nb/v2/analytics/default/prefixstats/"
28 print "incorrect stat type", stat_type
32 self.http = httplib2.Http(".cache")
33 self.http.add_credentials('admin', 'admin')
36 if (self.stat_type == Stats.TYPE_HOST):
37 return "host pair %s -> %s" % (self.src, self.dst)
38 elif (self.stat_type == Stats.TYPE_AL):
39 return "affinity link %s" % self.al
40 elif (self.stat_type == Stats.TYPE_PREFIX):
41 return "prefix %s" % self.subnet
43 return "unknown Stats type"
47 if (self.stat_type == Stats.TYPE_HOST):
48 resp, content = self.http.request(self.url_prefix + self.src + "/" + self.dst, "GET")
49 elif (self.stat_type == Stats.TYPE_AL):
50 resp, content = self.http.request(self.url_prefix + self.al, "GET")
51 elif (self.stat_type == Stats.TYPE_PREFIX):
52 resp, content = self.http.request(self.url_prefix + self.subnet, "GET")
54 self.stats = json.loads(content)
55 is_fast = self.handle_rate_ewma()
56 is_big = self.check_large_flow()
57 return [is_fast, is_big]
58 except Exception as e:
62 # Return hosts that transferred data into this entity. Right now only supports prefixes.
63 def get_incoming_hosts(self):
64 if (self.stat_type == Stats.TYPE_PREFIX):
65 resp, content = self.http.request(self.url_prefix + "incoming/" + self.subnet, "GET")
66 data = json.loads(content)
68 # IPs sometimes (always?) get returned as strings like /1.2.3.4; strip off the leading /
69 ips = [h.replace("/", "") for h in data['hosts']]
72 print "Stat type not supported for incoming hosts"
75 # EWMA calculation for bit rate. Returns true if there is an anomaly.
76 def handle_rate_ewma(self):
78 anomaly_threshold = 2.0
79 new_bitrate = self.get_bit_rate()
83 if self.rate_ewma == None:
84 self.rate_ewma = new_bitrate
86 new_rate_ewma = alpha * new_bitrate + (1 - alpha) * self.rate_ewma
87 if (self.rate_ewma > 0 and new_rate_ewma > anomaly_threshold * self.rate_ewma):
89 self.rate_ewma = new_rate_ewma
92 # Returns true if this is a large flow
93 def check_large_flow(self):
94 if (self.get_bytes() > 5 * (10**6)):
101 bytes = long(self.stats["byteCount"])
102 except Exception as e:
107 def get_bit_rate(self):
109 bitrate = float(self.stats["bitRate"])
110 except Exception as e: