-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy path5-cloudwatch-asg-mem.py
182 lines (149 loc) · 4.9 KB
/
5-cloudwatch-asg-mem.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
import boto
import winstats
from boto.ec2 import cloudwatch
from boto.utils import get_instance_metadata
def collect_memory_usage():
meminfo = winstats.get_mem_info()
mem_percent = meminfo.MemoryLoad
#print(mem_percent)
return meminfo.MemoryLoad
def send_custom_metrics(instance_id, region, metrics, namespace, unit):
cw = cloudwatch.connect_to_region(region)
ec2 = boto.connect_ec2()
instance = ec2.get_only_instances(instance_ids=[instance_id])[0]
if "aws:autoscaling:groupName" in instance.tags:
cw.put_metric_data(
namespace,
metrics.keys(),
metrics.values(),
unit=unit,
dimensions={"AutoScalingGroupName": instance.tags["aws:autoscaling:groupName"]}
)
if __name__ == "__main__":
metadata = get_instance_metadata()
instance_id = metadata["instance-id"]
region = metadata["placement"]["availability-zone"][0:-1]
mem_percent = collect_memory_usage()
send_custom_metrics(
instance_id,
region,
{"Autoscaling": mem_percent},
namespace="EC2/Autoscaling-3",
unit="Percent"
)
# import boto
# import psutil
# import re
# from boto.ec2 import cloudwatch
# from boto.utils import get_instance_metadata
#
#
# def collect_memory_usage():
# """
# Use /proc/meminfo and regular expression to grep system memory usage
# """
#
# meminfo = {}
# pattern = re.compile("([\w\(\)]+):\s*(\d+)(:?\s*(\w+))?")
# with open("/proc/meminfo") as f:
# for line in f:
# match = pattern.match(line)
# if match:
# meminfo[match.group(1)] = float(match.group(2))
# return meminfo
#
#
# def calculate_mem_usage_percentage():
# """
# Calculate MemUsage and SwapUsage for CloudWatch
# Return the two values as percentage
# """
#
# mem_usage = collect_memory_usage()
#
# mem_free = mem_usage["MemFree"] + mem_usage["Buffers"] + mem_usage["Cached"]
# mem_used = mem_usage["MemTotal"] - mem_free
# mem_percent = mem_used / mem_usage["MemTotal"] * 100
#
# if mem_usage["SwapTotal"] != 0:
# swap_used = mem_usage["SwapTotal"] - mem_usage["SwapFree"] - mem_usage["SwapCached"]
# swap_percent = swap_used / mem_usage["SwapTotal"] * 100
# else:
# swap_percent = 0
#
# return mem_percent, swap_percent
#
#
# def send_custom_metrics(instance_id, region, metrics, namespace, unit):
# """
# Send custom metrics to CloudWatch.
#
# Input:
# - instance_id is the unique ID of an EC2 instance
# - region is a valid AWS region string, e.g. us-east-1
# - metrics is expected to be a map of key (name) -> value pairs of metrics
# - namespace is a custom metric name, usually of the type Service/Attribute, e.g. EC2/Memory
# - unit is one of the acceptable units, see
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/API_MetricDatum.html
# """
#
# cw = cloudwatch.connect_to_region(region)
# ec2 = boto.connect_ec2()
#
# cw.put_metric_data(
# namespace,
# metrics.keys(),
# metrics.values(),
# unit=unit,
# dimensions={"InstanceId": instance_id}
# )
#
# # If the instance is also part of an Auto Scaling Group,
# # we also send the custom metric to the ASG
# instance = ec2.get_only_instances(instance_ids=[instance_id])[0]
#
# if "aws:autoscaling:groupName" in instance.tags:
# cw.put_metric_data(
# namespace,
# metrics.keys(),
# metrics.values(),
# unit=unit,
# dimensions={"AutoScalingGroupName": instance.tags["aws:autoscaling:groupName"]}
# )
#
#
# def should_autoscale(mem_percent, cpu_percent):
# """
# Given Memory and CPU Usage, return 2 if we should scale out (instances += 1),
# 0 if we should scale in (instances -= 1), or 1 if we should do nothing.
# """
#
# if cpu_percent >= HIGH_CPU_THRESHOLD or mem_percent >= HIGH_MEMORY_THRESHOLD:
# return 2
# elif cpu_percent < LOW_CPU_THRESHOLD and mem_percent < LOW_MEMORY_THRESHOLD:
# return 0
# return 1
#
#
# if __name__ == "__main__":
# metadata = get_instance_metadata()
# instance_id = metadata["instance-id"]
# region = metadata["placement"]["availability-zone"][0:-1]
#
# # Get the attributes (all in percentage) we want to push to CloudWatch
# mem_percent, swap_percent = calculate_mem_usage_percentage()
# memory_metrics = {
# "MemUsage": mem_percent,
# "SwapUsage": swap_percent
# }
# cpu_percent = psutil.cpu_percent(interval=.5)
#
# # Compute the custom autoscaling value and publish it to CloudWatch
# autoscaling_value = should_autoscale(mem_percent, cpu_percent)
# send_custom_metrics(
# instance_id,
# region,
# {"Autoscaling": autoscaling_value},
# namespace="EC2/Autoscaling",
# unit="Count"
# )