1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 18:41:03 +00:00

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

View file

@ -8,37 +8,26 @@ Usage:
./munin-profile-node.py munin.pcap ./munin-profile-node.py munin.pcap
""" """
import collections
import sys import sys
from scapy.utils import rdpcap from scapy.utils import rdpcap
import scapy.layers.l2 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): def __init__(self):
self.to_node = ""
self.from_node = ""
self.times = dict() self.times = dict()
self.idles = [] self.idles = []
self.curcommand = None self.curcommand = None
self.commandstart = 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): def handle_to_node(self, timestamp, line):
if self.curcommand is None and self.commandstart is not None: if self.curcommand is None and self.commandstart is not None:
self.idles.append(timestamp - self.commandstart) self.idles.append(timestamp - self.commandstart)
@ -55,6 +44,45 @@ class MuninProfiler:
self.curcommand = None self.curcommand = None
self.commandstart = timestamp 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(): def main():
mp = MuninProfiler() mp = MuninProfiler()
for pkt in rdpcap(sys.argv[1]): for pkt in rdpcap(sys.argv[1]):