munin-profile-node.py: hanlde multiple connections

This commit is contained in:
Helmut Grohne 2013-02-27 09:06:34 +01:00
parent f3c4c142df
commit 911a1a04ea
1 changed files with 49 additions and 21 deletions

View File

@ -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]):