A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
flowmon-parse-results.py
Go to the documentation of this file.
1 from __future__ import division
2 import sys
3 import os
4 try:
5  from xml.etree import cElementTree as ElementTree
6 except ImportError:
7  from xml.etree import ElementTree
8 
9 def parse_time_ns(tm):
10  if tm.endswith('ns'):
11  return long(tm[:-4])
12  raise ValueError(tm)
13 
14 
15 
16 class FiveTuple(object):
17  __slots__ = ['sourceAddress', 'destinationAddress', 'protocol', 'sourcePort', 'destinationPort']
18  def __init__(self, el):
19  self.sourceAddress = el.get('sourceAddress')
20  self.destinationAddress = el.get('destinationAddress')
21  self.sourcePort = int(el.get('sourcePort'))
22  self.destinationPort = int(el.get('destinationPort'))
23  self.protocol = int(el.get('protocol'))
24 
25 class Histogram(object):
26  __slots__ = 'bins', 'nbins', 'number_of_flows'
27  def __init__(self, el=None):
28  self.bins = []
29  if el is not None:
30  #self.nbins = int(el.get('nBins'))
31  for bin in el.findall('bin'):
32  self.bins.append( (float(bin.get("start")), float(bin.get("width")), int(bin.get("count"))) )
33 
34 class Flow(object):
35  __slots__ = ['flowId', 'delayMean', 'packetLossRatio', 'rxBitrate', 'txBitrate',
36  'fiveTuple', 'packetSizeMean', 'probe_stats_unsorted',
37  'hopCount', 'flowInterruptionsHistogram', 'rx_duration']
38  def __init__(self, flow_el):
39  self.flowId = int(flow_el.get('flowId'))
40  rxPackets = long(flow_el.get('rxPackets'))
41  txPackets = long(flow_el.get('txPackets'))
42  tx_duration = float(long(flow_el.get('timeLastTxPacket')[:-4]) - long(flow_el.get('timeFirstTxPacket')[:-4]))*1e-9
43  rx_duration = float(long(flow_el.get('timeLastRxPacket')[:-4]) - long(flow_el.get('timeFirstRxPacket')[:-4]))*1e-9
44  self.rx_duration = rx_duration
46  if rxPackets:
47  self.hopCount = float(flow_el.get('timesForwarded')) / rxPackets + 1
48  else:
49  self.hopCount = -1000
50  if rxPackets:
51  self.delayMean = float(flow_el.get('delaySum')[:-4]) / rxPackets * 1e-9
52  self.packetSizeMean = float(flow_el.get('rxBytes')) / rxPackets
53  else:
54  self.delayMean = None
55  self.packetSizeMean = None
56  if rx_duration > 0:
57  self.rxBitrate = long(flow_el.get('rxBytes'))*8 / rx_duration
58  else:
59  self.rxBitrate = None
60  if tx_duration > 0:
61  self.txBitrate = long(flow_el.get('txBytes'))*8 / tx_duration
62  else:
63  self.txBitrate = None
64  lost = float(flow_el.get('lostPackets'))
65  #print "rxBytes: %s; txPackets: %s; rxPackets: %s; lostPackets: %s" % (flow_el.get('rxBytes'), txPackets, rxPackets, lost)
66  if rxPackets == 0:
67  self.packetLossRatio = None
68  else:
69  self.packetLossRatio = (lost / (rxPackets + lost))
70 
71  interrupt_hist_elem = flow_el.find("flowInterruptionsHistogram")
72  if interrupt_hist_elem is None:
74  else:
75  self.flowInterruptionsHistogram = Histogram(interrupt_hist_elem)
76 
77 
78 class ProbeFlowStats(object):
79  __slots__ = ['probeId', 'packets', 'bytes', 'delayFromFirstProbe']
80 
81 class Simulation(object):
82  def __init__(self, simulation_el):
83  self.flows = []
84  FlowClassifier_el, = simulation_el.findall("Ipv4FlowClassifier")
85  flow_map = {}
86  for flow_el in simulation_el.findall("FlowStats/Flow"):
87  flow = Flow(flow_el)
88  flow_map[flow.flowId] = flow
89  self.flows.append(flow)
90  for flow_cls in FlowClassifier_el.findall("Flow"):
91  flowId = int(flow_cls.get('flowId'))
92  flow_map[flowId].fiveTuple = FiveTuple(flow_cls)
93 
94  for probe_elem in simulation_el.findall("FlowProbes/FlowProbe"):
95  probeId = int(probe_elem.get('index'))
96  for stats in probe_elem.findall("FlowStats"):
97  flowId = int(stats.get('flowId'))
98  s = ProbeFlowStats()
99  s.packets = int(stats.get('packets'))
100  s.bytes = long(stats.get('bytes'))
101  s.probeId = probeId
102  if s.packets > 0:
103  s.delayFromFirstProbe = parse_time_ns(stats.get('delayFromFirstProbeSum')) / float(s.packets)
104  else:
105  s.delayFromFirstProbe = 0
106  flow_map[flowId].probe_stats_unsorted.append(s)
107 
108 
109 def main(argv):
110  file_obj = open(argv[1])
111  print "Reading XML file ",
112 
113  sys.stdout.flush()
114  level = 0
115  sim_list = []
116  for event, elem in ElementTree.iterparse(file_obj, events=("start", "end")):
117  if event == "start":
118  level += 1
119  if event == "end":
120  level -= 1
121  if level == 0 and elem.tag == 'FlowMonitor':
122  sim = Simulation(elem)
123  sim_list.append(sim)
124  elem.clear() # won't need this any more
125  sys.stdout.write(".")
126  sys.stdout.flush()
127  print " done."
128 
129 
130  for sim in sim_list:
131  for flow in sim.flows:
132  t = flow.fiveTuple
133  proto = {6: 'TCP', 17: 'UDP'} [t.protocol]
134  print "FlowID: %i (%s %s/%s --> %s/%i)" % \
135  (flow.flowId, proto, t.sourceAddress, t.sourcePort, t.destinationAddress, t.destinationPort)
136  print "\tTX bitrate: %.2f kbit/s" % (flow.txBitrate*1e-3,)
137  print "\tRX bitrate: %.2f kbit/s" % (flow.rxBitrate*1e-3,)
138  print "\tMean Delay: %.2f ms" % (flow.delayMean*1e3,)
139  print "\tPacket Loss Ratio: %.2f %%" % (flow.packetLossRatio*100)
140 
141 
142 if __name__ == '__main__':
143  main(sys.argv)