From 2c3abc0bacb48cdbc6393f54b7eaf9cb4b1ea147 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Fri, 22 Oct 2010 14:59:56 +0100 Subject: [PATCH] Add example python script to parse Flow Monitor XML results. --- examples/flowmon/flowmon-parse-results.py | 143 ++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 examples/flowmon/flowmon-parse-results.py diff --git a/examples/flowmon/flowmon-parse-results.py b/examples/flowmon/flowmon-parse-results.py new file mode 100644 index 000000000..f0adf03be --- /dev/null +++ b/examples/flowmon/flowmon-parse-results.py @@ -0,0 +1,143 @@ +from __future__ import division +import sys +import os +try: + from xml.etree import cElementTree as ElementTree +except ImportError: + from xml.etree import ElementTree + +def parse_time_ns(tm): + if tm.endswith('ns'): + return long(tm[:-2]) + raise ValueError(tm) + + + +class FiveTuple(object): + __slots__ = ['sourceAddress', 'destinationAddress', 'protocol', 'sourcePort', 'destinationPort'] + def __init__(self, el): + self.sourceAddress = el.get('sourceAddress') + self.destinationAddress = el.get('destinationAddress') + self.sourcePort = int(el.get('sourcePort')) + self.destinationPort = int(el.get('destinationPort')) + self.protocol = int(el.get('protocol')) + +class Histogram(object): + __slots__ = 'bins', 'nbins', 'number_of_flows' + def __init__(self, el=None): + self.bins = [] + if el is not None: + #self.nbins = int(el.get('nBins')) + for bin in el.findall('bin'): + self.bins.append( (float(bin.get("start")), float(bin.get("width")), int(bin.get("count"))) ) + +class Flow(object): + __slots__ = ['flowId', 'delayMean', 'packetLossRatio', 'rxBitrate', 'txBitrate', + 'fiveTuple', 'packetSizeMean', 'probe_stats_unsorted', + 'hopCount', 'flowInterruptionsHistogram', 'rx_duration'] + def __init__(self, flow_el): + self.flowId = int(flow_el.get('flowId')) + rxPackets = long(flow_el.get('rxPackets')) + txPackets = long(flow_el.get('txPackets')) + tx_duration = float(long(flow_el.get('timeLastTxPacket')[:-2]) - long(flow_el.get('timeFirstTxPacket')[:-2]))*1e-9 + rx_duration = float(long(flow_el.get('timeLastRxPacket')[:-2]) - long(flow_el.get('timeFirstRxPacket')[:-2]))*1e-9 + self.rx_duration = rx_duration + self.probe_stats_unsorted = [] + if rxPackets: + self.hopCount = float(flow_el.get('timesForwarded')) / rxPackets + 1 + else: + self.hopCount = -1000 + if rxPackets: + self.delayMean = float(flow_el.get('delaySum')[:-2]) / rxPackets * 1e-9 + self.packetSizeMean = float(flow_el.get('rxBytes')) / rxPackets + else: + self.delayMean = None + self.packetSizeMean = None + if rx_duration > 0: + self.rxBitrate = long(flow_el.get('rxBytes'))*8 / rx_duration + else: + self.rxBitrate = None + if tx_duration > 0: + self.txBitrate = long(flow_el.get('txBytes'))*8 / tx_duration + else: + self.txBitrate = None + lost = float(flow_el.get('lostPackets')) + #print "rxBytes: %s; txPackets: %s; rxPackets: %s; lostPackets: %s" % (flow_el.get('rxBytes'), txPackets, rxPackets, lost) + if rxPackets == 0: + self.packetLossRatio = None + else: + self.packetLossRatio = (lost / (rxPackets + lost)) + + interrupt_hist_elem = flow_el.find("flowInterruptionsHistogram") + if interrupt_hist_elem is None: + self.flowInterruptionsHistogram = None + else: + self.flowInterruptionsHistogram = Histogram(interrupt_hist_elem) + + +class ProbeFlowStats(object): + __slots__ = ['probeId', 'packets', 'bytes', 'delayFromFirstProbe'] + +class Simulation(object): + def __init__(self, simulation_el): + self.flows = [] + FlowClassifier_el, = simulation_el.findall("Ipv4FlowClassifier") + flow_map = {} + for flow_el in simulation_el.findall("FlowStats/Flow"): + flow = Flow(flow_el) + flow_map[flow.flowId] = flow + self.flows.append(flow) + for flow_cls in FlowClassifier_el.findall("Flow"): + flowId = int(flow_cls.get('flowId')) + flow_map[flowId].fiveTuple = FiveTuple(flow_cls) + + for probe_elem in simulation_el.findall("FlowProbes/FlowProbe"): + probeId = int(probe_elem.get('index')) + for stats in probe_elem.findall("FlowStats"): + flowId = int(stats.get('flowId')) + s = ProbeFlowStats() + s.packets = int(stats.get('packets')) + s.bytes = long(stats.get('bytes')) + s.probeId = probeId + if s.packets > 0: + s.delayFromFirstProbe = parse_time_ns(stats.get('delayFromFirstProbeSum')) / float(s.packets) + else: + s.delayFromFirstProbe = 0 + flow_map[flowId].probe_stats_unsorted.append(s) + + +def main(argv): + file_obj = open(argv[1]) + print "Reading XML file ", + + sys.stdout.flush() + level = 0 + sim_list = [] + for event, elem in ElementTree.iterparse(file_obj, events=("start", "end")): + if event == "start": + level += 1 + if event == "end": + level -= 1 + if level == 0 and elem.tag == 'FlowMonitor': + sim = Simulation(elem) + sim_list.append(sim) + elem.clear() # won't need this any more + sys.stdout.write(".") + sys.stdout.flush() + print " done." + + + for sim in sim_list: + for flow in sim.flows: + t = flow.fiveTuple + proto = {6: 'TCP', 17: 'UDP'} [t.protocol] + print "FlowID: %i (%s %s/%s --> %s/%i)" % \ + (flow.flowId, proto, t.sourceAddress, t.sourcePort, t.destinationAddress, t.destinationPort) + print "\tTX bitrate: %.2f kbit/s" % (flow.txBitrate*1e-3,) + print "\tRX bitrate: %.2f kbit/s" % (flow.rxBitrate*1e-3,) + print "\tMean Delay: %.2f ms" % (flow.delayMean*1e3,) + print "\tPacket Loss Ratio: %.2f %%" % (flow.packetLossRatio*100) + + +if __name__ == '__main__': + main(sys.argv)