From 911a1a04ea48de7af2f24adf566a7f20d8768f01 Mon Sep 17 00:00:00 2001 From: Helmut Grohne Date: Wed, 27 Feb 2013 09:06:34 +0100 Subject: [PATCH] munin-profile-node.py: hanlde multiple connections --- tools/profiling/munin-profile-node.py | 70 +++++++++++++++++++-------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/tools/profiling/munin-profile-node.py b/tools/profiling/munin-profile-node.py index bd2cf215..f59f9f18 100755 --- a/tools/profiling/munin-profile-node.py +++ b/tools/profiling/munin-profile-node.py @@ -8,37 +8,26 @@ Usage: ./munin-profile-node.py munin.pcap """ +import collections import sys from scapy.utils import rdpcap import scapy.layers.l2 -from scapy.layers.inet import TCP +from scapy.layers.inet import IP, TCP -class MuninProfiler: +class ConnectionProfile: + """ + @ivar times: mapping of commands to durations waiting for answers in + seconds + @type times: {str: [float]} + @ivar idles: list of durations waiting for client in seconds + @type idles: [float] + """ def __init__(self): - self.to_node = "" - self.from_node = "" self.times = dict() self.idles = [] self.curcommand = None self.commandstart = None - def handle_packet(self, packet): - payload = str(packet[TCP].payload) - if not payload: - return - if packet[TCP].dport == 4949: - self.to_node += payload - else: - self.from_node += payload - lines = self.to_node.split("\n") - self.to_node = lines.pop() - for line in lines: - self.handle_to_node(packet.time, line) - lines = self.from_node.split("\n") - self.from_node = lines.pop() - for line in lines: - self.handle_from_node(packet.time, line) - def handle_to_node(self, timestamp, line): if self.curcommand is None and self.commandstart is not None: self.idles.append(timestamp - self.commandstart) @@ -55,6 +44,45 @@ class MuninProfiler: self.curcommand = None self.commandstart = timestamp +class MuninProfiler: + def __init__(self): + self.to_node = "" + self.from_node = "" + self.connprof = collections.defaultdict(ConnectionProfile) + + def handle_packet(self, packet): + payload = str(packet[TCP].payload) + if not payload: + return + if packet[TCP].dport == 4949: + self.to_node += payload + conn = (packet[IP].src, packet[TCP].sport, packet[IP].dst) + elif packet[TCP].sport == 4949: + self.from_node += payload + conn = (packet[IP].dst, packet[TCP].dport, packet[IP].src) + else: + return + lines = self.to_node.split("\n") + self.to_node = lines.pop() + for line in lines: + self.connprof[conn].handle_to_node(packet.time, line) + lines = self.from_node.split("\n") + self.from_node = lines.pop() + for line in lines: + self.connprof[conn].handle_from_node(packet.time, line) + + @property + def times(self): + times = dict() + for prof in self.connprof.values(): + for com, durations in prof.times.items(): + times.setdefault(com, []).extend(durations) + return times + + @property + def idles(self): + return sum((prof.idles for prof in self.connprof.values()), []) + def main(): mp = MuninProfiler() for pkt in rdpcap(sys.argv[1]):