first commit.
David Blume authored 5 years ago
|
1) #!/usr/bin/python3
2) #
3) # Since this is meant to be run as a daemon, do not use #!/usr/bin/env python3,
4) # because the process name would then be python3, not based on __FILE__.
5) #
6) # [filename] -d 3 192.168.1.1 192.168.1.12 &
7) # disown [jobid]
8) import os
9) import sys
10) import subprocess
11) import time
12) from argparse import ArgumentParser
13) import threading
14) import queue
|
first commit.
David Blume authored 5 years ago
|
41) status = "UP" if success else "DOWN"
42) _print_queue.put([f'{time.strftime("%Y-%m-%d %H:%M:%S", now)} {host} {status}'])
43) _ping_queue.task_done()
44)
45)
46) def ping(host):
47) """Returns True if host (str) responds to a ping request."""
48) return subprocess.call([*_ping_cmd, host], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) == 0
49)
50)
51) def print_manager():
52) """The only thread allowed to write output."""
53) while True:
54) job = _print_queue.get()
55) for line in job:
56) log(line)
57) _print_queue.task_done()
58)
59)
60) def log(*args, **kwargs):
61) """Opens the logfile, writes the log, and closes the logfile."""
62) # I don't leave the log file open for writing because another process needs access too.
63) with open(_logname, 'a') as fp:
64) return print(*args, **kwargs, file=fp)
65)
66)
67) if __name__ == '__main__':
68) parser = ArgumentParser(description="Repeatedly ping sites. Ex: %(prog)s -d 3 192.168.1.1 192.168.1.12")
69) parser.add_argument('-d', '--delay', type=float, default=1.0, help='Delay between pings')
70) parser.add_argument('addresses', nargs='+', help='Addresses to ping')
71) parser_args = parser.parse_args()
72)
73) _results = dict()
74) for addr in parser_args.addresses:
75) _results[addr] = None
76) delay = parser_args.delay
77)
78) _ping_queue = queue.Queue(2 * len(parser_args.addresses)) # No more than 2 pending pings per address
79) _print_queue = queue.Queue()
80)
81) _logname = os.path.join(os.path.expanduser('~'), 'log', os.path.basename(sys.argv[0]).replace('py', 'txt'))
82) _pid = os.getpid()
83)
84) # Choose the ping parameters appropriate for the platform
85) if sys.platform == 'cygwin' or sys.platform == 'win32':
86) _ping_cmd = ('ping', '-n', '1', '-w', '2000')
87) else:
88) _ping_cmd = ('ping', '-c', '1', '-W', '2', '-q')
89)
90) for i in range(len(parser_args.addresses)):
91) t = threading.Thread(target=pinger, daemon=True)
92) t.start()
93) del t
94)
95) t = threading.Thread(target=print_manager, daemon=True)
96) t.start()
97) del t
98)
99) _print_queue.put([f'{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())}'
|
Add notifications for SIGTE...
David Blume authored 5 years ago
|
100) f' PID={os.getpid()} repeat={delay}s addresses={",".join(parser_args.addresses)} Starting'])
101)
102) signal.signal(signal.SIGINT, log_exit)
103) signal.signal(signal.SIGTERM, log_exit)
104)
|