blob: e8fed92e71a9d67e74d868fba04bb2231954feee [file] [log] [blame]
awlane1cec2332025-04-24 17:24:47 -05001import re
2from time import sleep
3from io import TextIOWrapper
4from threading import Thread
5
6import msgpack
7
8from mininet.node import Node
9from minindn.util import host_home
10from minindn.minindn_play.socket import PlaySocket
11from minindn.minindn_play.consts import WSKeys, WSFunctions
12
13
14class LogMonitor:
15 nodes: list[Node]
16 log_file: str
17 interval: float
18 socket: PlaySocket
19 filter: re.Pattern
20 quit: bool = False
21
22 def __init__(self, nodes: list, log_file: str, interval: float = 0.5, regex_filter: str = ''):
23 self.nodes = nodes
24 self.log_file = log_file
25 self.interval = interval
26 self.regex_filter = re.compile(regex_filter)
27
28 def start(self, socket: PlaySocket):
29 self.socket = socket
30 Thread(target=self._start).start()
31
32 def stop(self):
33 self.quit = True
34
35 def _start(self):
36 files: list[TextIOWrapper] = []
37 counts: dict[str, int] = {}
38
39 for node in self.nodes:
40 path = f"{host_home(node)}/{self.log_file}"
41 files.append(open(path, 'r'))
42 counts[node.name] = 0
43
44 while not self.quit:
45 for i, file in enumerate(files):
46 node = self.nodes[i]
47 counts[node.name] = 0
48 while line := file.readline():
49 if self.regex_filter.match(line):
50 counts[node.name] += 1
51
52 self._send(counts)
53 sleep(self.interval)
54
55 for file in files:
56 file.close()
57
58 def _send(self, counts: dict[str, int]):
59 self.socket.send_all(msgpack.dumps({
60 WSKeys.MSG_KEY_FUN: WSFunctions.MONITOR_COUNTS,
61 WSKeys.MSG_KEY_RESULT: counts,
62 }))