munin-profile-node.py: hanlde multiple connections
This commit is contained in:
parent
f3c4c142df
commit
911a1a04ea
|
@ -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]):
|
||||
|
|
Loading…
Reference in New Issue