最後活躍 1744985631

./ping_monitor.py 8.8.8.8

gistfile1.txt 原始檔案
1Пример вывода при успешном
2```
3Ping monitor for example.com
4
5Status: pinging... (connection stable)
6Current series: packets_lost=0 | duration=0.0 sec | 2023-05-15 14:30:45
7
8Press Ctrl+C to exit...
9```
10
11Пример вывода при потере пакетов
12```
13Ping monitor for example.com
14
15Status: CONNECTION LOST!
16Current series: packets_lost=3 | duration=3.0 sec | started at 2023-05-15 14:31:02
17
18Outage history (sorted by packets lost):
19------------------------------------------------------------
20Start: 2023-05-15 14:25:10 | Packets lost: 5 | Duration: 5.0 sec
21Start: 2023-05-15 14:20:30 | Packets lost: 2 | Duration: 2.0 sec
22
23Press Ctrl+C to exit...
24```
ping_monitor.py 原始檔案
1#!/usr/bin/env python3
2import sys
3import subprocess
4import time
5from datetime import datetime
6from collections import deque
7
8class PingMonitor:
9 def __init__(self, host):
10 self.host = host
11 self.current_outage = None
12 self.outages = deque(maxlen=100) # Ограничиваем количество хранимых серий
13 self.last_success_time = datetime.now()
14
15 def ping_host(self):
16 try:
17 # -c 1: один пакет, -W 1: таймаут 1 секунда (для Linux)
18 # Для Windows нужно использовать "-n 1 -w 1000"
19 result = subprocess.run(['ping', '-c', '1', '-W', '1', self.host],
20 stdout=subprocess.PIPE,
21 stderr=subprocess.PIPE,
22 text=True)
23 return result.returncode == 0
24 except Exception as e:
25 print(f"Error pinging host: {e}")
26 return False
27
28 def monitor(self):
29 while True:
30 success = self.ping_host()
31 now = datetime.now()
32
33 if not success and self.current_outage is None:
34 # Начало новой серии разрывов
35 self.current_outage = {
36 'start': now,
37 'packets_lost': 1,
38 'end': None
39 }
40 elif not success and self.current_outage is not None:
41 # Продолжение текущей серии разрывов
42 self.current_outage['packets_lost'] += 1
43 elif success and self.current_outage is not None:
44 # Серия разрывов закончилась
45 self.current_outage['end'] = now
46 self.outages.append(self.current_outage)
47 self.current_outage = None
48 self.last_success_time = now
49 elif success:
50 # Успешный пинг, обновляем время последнего успеха
51 self.last_success_time = now
52
53 self.print_status()
54 time.sleep(1) # Пауза между пингами
55
56 def print_status(self):
57 # Очищаем экран (работает в терминалах, поддерживающих ANSI коды)
58 print("\033c", end="")
59 print(f"Ping monitor for {self.host}\n")
60
61 # Всегда показываем текущий статус
62 if self.current_outage is None:
63 print("Status: pinging... (connection stable)")
64 current_duration = (datetime.now() - self.last_success_time).total_seconds()
65 print(f"Current series: packets_lost=0 | duration={current_duration:.1f} sec | {datetime.now()}")
66 else:
67 current_duration = (datetime.now() - self.current_outage['start']).total_seconds()
68 print(f"Status: CONNECTION LOST!")
69 print(f"Current series: packets_lost={self.current_outage['packets_lost']} | "
70 f"duration={current_duration:.1f} sec | started at {self.current_outage['start']}")
71
72 # Выводим историю разрывов, если они есть
73 if self.outages:
74 print("\nOutage history (sorted by packets lost):")
75 print("-" * 60)
76
77 # Сортируем серии по количеству потерянных пакетов (по убыванию)
78 sorted_outages = sorted(self.outages,
79 key=lambda x: x['packets_lost'],
80 reverse=True)
81
82 for outage in sorted_outages:
83 duration = (outage['end'] - outage['start']).total_seconds()
84 print(f"Start: {outage['start']} | "
85 f"Packets lost: {outage['packets_lost']} | "
86 f"Duration: {duration:.1f} sec")
87
88 print("\nPress Ctrl+C to exit...")
89
90def main():
91 if len(sys.argv) != 2:
92 print("Usage: ./ping_monitor.py <host>")
93 sys.exit(1)
94
95 host = sys.argv[1]
96 monitor = PingMonitor(host)
97
98 try:
99 monitor.monitor()
100 except KeyboardInterrupt:
101 print("\nMonitoring stopped.")
102
103if __name__ == "__main__":
104 main()