Browse files

munin-profile-node.py: hanlde multiple connections

  • Loading branch information...
1 parent f3c4c14 commit 911a1a04ea48de7af2f24adf566a7f20d8768f01 @helmutg helmutg committed Feb 27, 2013
Showing with 49 additions and 21 deletions.
  1. +49 −21 tools/profiling/munin-profile-node.py
View
70 tools/profiling/munin-profile-node.py
@@ -8,37 +8,26 @@
./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 @@ def handle_from_node(self, timestamp, line):
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]):

0 comments on commit 911a1a0

Please sign in to comment.