Initial commit
This commit is contained in:
commit
ffa6b3797e
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
.idea/
|
||||||
|
data/
|
1
README.md
Normal file
1
README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
To proof how poor designed (my) telekom routers are, this repo pings the ips **1.1.1.1** (cloudflare), **217.237.148.22** (telekom dns), **192.168.2.1** (router) and stores the request times into a csv file. -1 is timeout (which is set to 100 seconds)
|
167
main.py
Normal file
167
main.py
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
import csv
|
||||||
|
import signal
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
|
||||||
|
import ping3
|
||||||
|
|
||||||
|
|
||||||
|
class Ping(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
super().__init__()
|
||||||
|
self._start: int = None
|
||||||
|
self._end: int = None
|
||||||
|
self._ping: int = None
|
||||||
|
|
||||||
|
self.ip = ip
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
self._start = time.time_ns() / 1_000_000
|
||||||
|
self._ping = ping3.ping(self.ip, timeout=60, unit="ms") or -1
|
||||||
|
self._end = time.time_ns() / 1_000_000
|
||||||
|
|
||||||
|
def load(self) -> (int, int, int):
|
||||||
|
self.join()
|
||||||
|
return self._start, self._end, self._ping
|
||||||
|
|
||||||
|
|
||||||
|
class PingRequester(threading.Thread):
|
||||||
|
|
||||||
|
def __init__(self, ip: str, file: str):
|
||||||
|
super().__init__()
|
||||||
|
self.stop = False
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.event = threading.Event()
|
||||||
|
|
||||||
|
self.write_interval = 100
|
||||||
|
|
||||||
|
self.ip = ip
|
||||||
|
self.list: [Ping] = []
|
||||||
|
self.file = open(file, 'a+')
|
||||||
|
self.writer = csv.writer(self.file)
|
||||||
|
|
||||||
|
def run(self) -> None:
|
||||||
|
while not self.stop:
|
||||||
|
threading.Thread(target=self._ping).start()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for req in self.list:
|
||||||
|
data.append(req.load())
|
||||||
|
self._write(data)
|
||||||
|
|
||||||
|
def finish(self) -> None:
|
||||||
|
self.stop = True
|
||||||
|
|
||||||
|
def _ping(self) -> None:
|
||||||
|
self.lock.acquire()
|
||||||
|
request = Ping(self.ip)
|
||||||
|
request.start()
|
||||||
|
self.list.append(request)
|
||||||
|
|
||||||
|
if len(self.list) >= self.write_interval and not self.event.is_set():
|
||||||
|
self.event.set()
|
||||||
|
self.lock.release()
|
||||||
|
data = []
|
||||||
|
for req in self.list[:self.write_interval]:
|
||||||
|
data.append(req.load())
|
||||||
|
self.list = self.list[self.write_interval:]
|
||||||
|
self._write(data)
|
||||||
|
|
||||||
|
self.event.clear()
|
||||||
|
else:
|
||||||
|
self.lock.release()
|
||||||
|
|
||||||
|
def _write(self, data: [(int, int, int)]) -> None:
|
||||||
|
self.writer.writerows(data)
|
||||||
|
self.file.flush()
|
||||||
|
|
||||||
|
|
||||||
|
class BulkPing:
|
||||||
|
|
||||||
|
def __init__(self, file: str, *ips: str):
|
||||||
|
self.ips = ips
|
||||||
|
|
||||||
|
self.event = threading.Event()
|
||||||
|
|
||||||
|
self.write_interval = 100
|
||||||
|
|
||||||
|
self.list: [[Ping]] = [[] for _ in range(len(ips))]
|
||||||
|
self.stop = False
|
||||||
|
self.file = open(file, 'a+')
|
||||||
|
self.writer = csv.writer(self.file)
|
||||||
|
|
||||||
|
def start(self) -> None:
|
||||||
|
while not self.stop:
|
||||||
|
for i, ip in enumerate(self.ips):
|
||||||
|
ping = Ping(ip)
|
||||||
|
ping.start()
|
||||||
|
self.list[i].append(ping)
|
||||||
|
|
||||||
|
if not self.event.is_set() and all(len(pings) >= self.write_interval for pings in self.list):
|
||||||
|
self.event.set()
|
||||||
|
threading.Thread(target=self._write_cached_pings).start()
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def finish(self) -> None:
|
||||||
|
self.stop = True
|
||||||
|
|
||||||
|
def _write_cached_pings(self) -> None:
|
||||||
|
rows = []
|
||||||
|
|
||||||
|
for i in range(self.write_interval):
|
||||||
|
data = []
|
||||||
|
for pings in self.list:
|
||||||
|
data.append(pings[i].load()[2])
|
||||||
|
rows.append(data)
|
||||||
|
|
||||||
|
for i in range(len(self.list)):
|
||||||
|
self.list[i] = self.list[i][self.write_interval:]
|
||||||
|
|
||||||
|
self._write(rows)
|
||||||
|
self.event.clear()
|
||||||
|
|
||||||
|
def _write(self, rows: [[int]]):
|
||||||
|
self.writer.writerows(rows)
|
||||||
|
self.file.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def v1():
|
||||||
|
threads = [
|
||||||
|
PingRequester('1.1.1.1', 'data/1-1-1-1.csv'),
|
||||||
|
PingRequester('217.237.148.22', 'data/217-237-148-22.csv'),
|
||||||
|
PingRequester('192.168.2.1', 'data/192-168-2-1.csv')
|
||||||
|
]
|
||||||
|
|
||||||
|
def stop(sig, frame):
|
||||||
|
print("Stopping threads gratefully (may take up to 60 seconds)")
|
||||||
|
for thread in threads:
|
||||||
|
thread.finish()
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, stop)
|
||||||
|
|
||||||
|
for i, thread in enumerate(threads):
|
||||||
|
thread.start()
|
||||||
|
print(f'Started thread {i}')
|
||||||
|
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
|
||||||
|
|
||||||
|
def v2():
|
||||||
|
ping = BulkPing('data/all.csv',
|
||||||
|
'1.1.1.1', '217.237.148.22', '192.168.2.1')
|
||||||
|
|
||||||
|
def stop(sig, frame):
|
||||||
|
print("Stopping process gratefully (may take up to 60 seconds)")
|
||||||
|
ping.finish()
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, stop)
|
||||||
|
|
||||||
|
ping.start()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
v2()
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
ping3~=3.0.2
|
Reference in New Issue
Block a user