forked from mlavin/cloudping
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcloudping.py
More file actions
103 lines (97 loc) · 3.11 KB
/
cloudping.py
File metadata and controls
103 lines (97 loc) · 3.11 KB
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
from __future__ import unicode_literals
import boto3
import datetime
import requests
import json
def ping(event, context):
"""Ping the status of a webpage."""
options = {
'domain': 'example.com',
'protocol': 'http',
'path': '/',
'method': 'GET',
'allow_redirects': "False",
'timeout': 5,
'verify_response_contains': '',
'certfile_s3': None,
}
options.update(event)
url = '{protocol}://{domain}{path}'.format(**options)
response_time = None
if options['certfile_s3']:
s3 = boto3.resource('s3')
s3.Bucket('binogi-cloudping-cert-authorities').download_file(options['certfile_s3'], '/tmp/cafile.pem')
verify = '/tmp/cafile.pem'
else:
verify = True
try:
response = requests.request(
options['method'],
url,
allow_redirects=(options['allow_redirects'] == "True"),
timeout=options['timeout'],
verify=verify)
response.raise_for_status()
response_time = response.elapsed.total_seconds()
if options['verify_response_contains'] in response.text:
result_value = 0
else:
print("Could not find required string in response", response.text)
result_value = 1
except Exception as e:
print(str(e))
result_value = 1
# I tried to mock response.elapsed.total_seconds() but failed miserably because I am a python noob. This change
# allows the tests to run and does not interfere with the normal use case. Previously this would fail in tests
# because response_time is an Mock object and is not json dumpable.
print(json.dumps({
'cloudping_result': result_value,
'response_time': 5 if isinstance(response_time, object) else response_time,
'url': url,
'options': options
}))
client = boto3.client('cloudwatch')
dimensions = [
{
'Name': 'url',
'Value': url
},
{
'Name': 'method',
'Value': options['method']
},
{
'Name': 'protocol',
'Value': options['protocol']
},
]
timestamp = datetime.datetime.utcnow()
# client.put_metric_data(
# Namespace='cloudping',
# MetricData=[
# {
# 'MetricName': 'status',
# 'Dimensions': dimensions,
# 'Timestamp': timestamp,
# 'Value': result_value,
# 'Unit': 'None',
# 'StorageResolution': 60
# },
# ]
# )
# For cost saving reasons, only send ONE metric. If http status code or contents are not good, don't care about response time!
if result_value != 0:
response_time = 999
client.put_metric_data(
Namespace='cloudping',
MetricData=[
{
'MetricName': 'responseTime',
'Dimensions': dimensions,
'Timestamp': timestamp,
'Value': response_time,
'Unit': 'Seconds',
'StorageResolution': 60
},
]
)