-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprobe_internet.py
106 lines (98 loc) · 3.13 KB
/
probe_internet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import argparse
from datetime import datetime
from humanize import naturaldelta
import logging
import socket
import sys
import time
import toml
from twilio.rest import Client as TwilioClient
log = logging.getLogger(__name__)
def notify_sms(
lost_time,
account_id,
auth_token,
source_phone_number,
target_phone_number,
min_interval=0,
):
lost_duration = datetime.utcnow() - lost_time
if lost_duration.total_seconds() < min_interval:
log.info('skipping sms, internet was not out long enough')
return
lost_duration = naturaldelta(lost_duration)
body = (
'Internet dropped at {} ({}).'
.format(lost_time, lost_duration)
)
try:
twilio = TwilioClient(account_id, auth_token)
twilio.messages.create(
body=body,
from_=source_phone_number,
to=target_phone_number,
)
except Exception:
log.exception('squashing error sending sms')
def probe_internet(host, port, timeout=3):
try:
socket.setdefaulttimeout(timeout)
log.debug('probing {}:{}'.format(host, port))
socket.socket(socket.AF_INET, socket.SOCK_STREAM).connect((host, port))
return True
except socket.error as ex:
log.debug('probe failed={}'.format(ex))
return False
def runloop(probe, probe_interval=5, notifier=None):
lost_time = None
while True:
start = datetime.utcnow()
result = probe()
if result:
if lost_time is not None:
log.info('internet is back!')
if notifier is not None:
notifier(lost_time)
lost_time = None
else:
log.debug('internet is up')
elif lost_time is None:
lost_time = start
log.warn('internet is out')
else:
log.info('internet still out')
delay = probe_interval - (datetime.utcnow() - start).total_seconds()
if delay > 0:
time.sleep(delay)
def parse_options(args):
parser = argparse.ArgumentParser()
parser.add_argument('-v', '--verbose', action='store_true')
parser.add_argument('--profile', default='profile.toml')
opts = parser.parse_args(args)
return opts
def main(args=sys.argv[1:]):
opts = parse_options(args)
logging.basicConfig(
level=logging.DEBUG if opts.verbose else logging.INFO,
format='%(asctime)-15s %(levelname)-8s [%(name)s] %(message)s',
)
with open(opts.profile, 'r') as fp:
profile = toml.load(fp)
def probe():
return probe_internet(
profile['probe']['ip'],
port=profile['probe']['port'],
timeout=profile['probe']['timeout'],
)
def notifier(lost_time):
notify_sms(
lost_time,
profile['twilio']['account_sid'],
profile['twilio']['auth_token'],
profile['twilio']['source_phone_number'],
profile['twilio']['target_phone_number'],
profile['twilio'].get('min_interval', 0),
)
runloop(probe, profile['probe']['interval'], notifier)
if __name__ == '__main__':
sys.exit(main())