in resources/code/Monitoring/create-cw-dashboard.py [0:0]
def create_cw_dashboard(ec2_list, networklimit):
widgets = {"widgets": []}
number = 1
# EBS to the EC2
for ec2instance in ec2_list:
instance_name = get_instance_name(ec2instance)
ec2instance_type = ec2.Instance(ec2instance)
ec2_details = ec2client.describe_instance_types(InstanceTypes=[ec2instance_type.instance_type])
ebs_volumes = get_ebs(ec2instance) ## get all EBS volumes per instance
## New instance Header
new_widget = {
"type": "text",
"width": 24,
"height": 4,
"properties": {
"markdown": f'\n# Report #{number}\
\n\n**Instance ID:** {ec2instance} \
\n\n**Tag:Name:** {instance_name} \
\n\n**InstanceType:** {ec2instance_type.instance_type} \
\n\n**Attached Volumes:** {ebs_volumes}'
}
}
widgets['widgets'].append(new_widget)
## Instance -> Internet Gateway
new_widget = {
"type": "text",
"width": 24,
"height": 2,
"properties": {
"markdown": "\n## " + "EC2 (" + ec2instance_type.instance_type + ") --> " + "Network" +"\n"
}
}
widgets['widgets'].append(new_widget)
ec2_NetworkInfo = ec2_details['InstanceTypes'][0]['NetworkInfo']
# Extract the number
numbers = []
for word in ec2_NetworkInfo['NetworkPerformance'].split():
if word.isdigit():
numbers.append(int(word))
if(len(numbers) == 0):
numbers.append(5)
# EC2 Metrics
new_widget = {
"type": "metric",
"width": 24,
"properties": {
"metrics": [
[ { "expression": "SUM(METRICS('network'))/PERIOD(networkOut)", "label": "Bandwidth (Bytes)", "id": "bandwidthBytes", "visible": False , "period": 300} ],
[ { "expression": "bandwidthBytes*0.000008", "label": "Bandwidth (Mbps - Megabits)", "id": "bandwidthMbps" , "period": 300} ], # Convert Bytes to Megabits -> 1 B = 0.000008 Mb
[ "AWS/EC2", "NetworkIn", "InstanceId", ec2instance, { "visible": False, "id": "networkIn", "period": 300 } ],
[ "AWS/EC2", "NetworkOut", "InstanceId", ec2instance, { "visible": False, "id": "networkOut" , "period": 300} ]
],
"view": "timeSeries",
"stacked": False,
"region": region,
"stat": "Sum",
"period": 300,
"title": ec2instance + " --> Network",
"annotations": {
"horizontal": [
{
"label": "Maximum Throughput (Mbps)",
"value": numbers[0]*1000
}
]
}
}
}
widgets['widgets'].append(new_widget)
## Instance -> EBS
new_widget = {
"type": "text",
"width": 24,
"height": 2,
"properties": {
"markdown": "\n## " + "Amazon EC2" + " --> " + "Amazon EBS" +"\n"
}
}
widgets['widgets'].append(new_widget)
if(networklimit['InstanceTypes'][ec2instance_type.instance_type]['EbsInfo']['EbsOptimizedSupport'] != 'unsupported'):
network_to_ebs = networklimit['InstanceTypes'][ec2instance_type.instance_type]['EbsInfo']['EbsOptimizedInfo']['MaximumBandwidthInMbps']
network_to_ebs_half = network_to_ebs*0.5
network_to_ebs_iops = networklimit['InstanceTypes'][ec2instance_type.instance_type]['EbsInfo']['EbsOptimizedInfo']['MaximumIops']
network_to_ebs_iops_half = network_to_ebs_iops*0.5
else:
network_to_ebs = 0
network_to_ebs_half = 0
network_to_ebs_iops = 0
network_to_ebs_iops_half = 0
new_widget = {
"type": "metric",
"width": 12,
"properties": {
"metrics": [
[ { "expression": "SUM(METRICS('ebs'))/PERIOD(ebsReadBytes)", "label": "Total IO In Bytes", "id": "totalIOBytes", "visible": False , "period": 300 } ], # (ebsReadBytes + ebsWriteBytes) / Period
[ { "expression": "totalIOBytes*0.000008", "label": "Bandwidth (Mbps - Megabits)", "id": "bandwidthMbps" , "period": 300} ], # Convert Bytes to Megabits -> 1 B = 0.000008 Mb
[ "AWS/EC2", "EBSReadBytes", "InstanceId", ec2instance, { "visible": False, "id": "ebsReadBytes", "period": 300 } ],
[ ".", "EBSWriteBytes", ".", ".", { "visible": False, "id": "ebsWriteBytes", "period": 300 } ]
],
"view": "timeSeries",
"stacked": False,
"region": region,
"stat": "Sum",
"period": 300,
"title": ec2instance + " -> EBS (Throughput)",
"annotations": {
"horizontal": [
{
"label": "Maximum Throughput (Mbps)",
"value": network_to_ebs
},
{
"label": "50% Throughput (Mbps)",
"value": network_to_ebs_half
}
]
}
}
}
widgets['widgets'].append(new_widget)
new_widget = {
"type": "metric",
"width": 12,
"properties": {
"metrics": [
[ { "expression": "SUM(METRICS('ebs'))/PERIOD(ebsWriteOps)", "label": "Total IOPS", "id": "totalIOPS", "visible": True , "period": 300 } ],
[ "AWS/EC2", "EBSWriteOps", "InstanceId", ec2instance, { "visible": False, "id": "ebsReadOps", "period": 300 } ],
[ ".", "EBSReadOps", ".", ".", { "visible": False, "id": "ebsWriteOps", "period": 300 } ]
],
"view": "timeSeries",
"stacked": False,
"region": region,
"stat": "Sum",
"period": 300,
"title": ec2instance + " -> Amazon EBS (IOPS)",
"annotations": {
"horizontal": [
{
"label": "Maximum IOPS",
"value": network_to_ebs_iops
},
{
"label": "50% IOPS",
"value": network_to_ebs_iops_half
}
]
}
}
}
widgets['widgets'].append(new_widget)
## EBS -> Instance
new_widget = {
"type": "text",
"width": 24,
"height": 2,
"properties": {
"markdown": "\n## Amazon EBS --> Amazon EC2 \n"
}
}
widgets['widgets'].append(new_widget)
for volume in ebs_volumes:
volume_speed = ec2.Volume(volume)
new_widget = {
"type": "text",
"width": 24,
"height": 2,
"properties": {
"markdown": "\n### InstanceID: " +ec2instance + " Volume: "+ volume +" ("+volume_speed.volume_type +")\n"
}
}
widgets['widgets'].append(new_widget)
## Volume Throughput
new_widget = {
"type": "metric",
"width": 12,
"properties": {
"metrics": [
[ { "expression": "SUM(METRICS('volume'))/PERIOD(volumeReadBytes)", "label": "Total IO (Bytes)", "id": "volumeThroughputBytes", "visible": False, "stat": "Sum", "period": 300 } ],
[ { "expression": "volumeThroughputBytes/1024/1024", "label": "Total Throughput (MB/s - MegaBytes per second)", "id": "volumeThroughputMBps", "stat": "Sum", "period": 300 } ],
[ "AWS/EBS", "VolumeWriteBytes", "VolumeId", volume, { "visible": False, "id": "volumeWriteBytes", "period": 300 } ],
[ "AWS/EBS", "VolumeReadBytes", "VolumeId", volume, { "visible": False, "id": "volumeReadBytes", "period": 300 } ]
],
"view": "timeSeries",
"stacked": False,
"region": region,
"stat": "Sum",
"period": 300,
"yAxis": {
"left": {
"showUnits": False,
"label": "MiB/s"
},
"right": {
"showUnits": False
}
},
"title": "Throughput" + "(" + volume +")"
}
}
# Add space for annotations
new_widget['properties'].update({'annotations': {'horizontal': []}})
flagForIOPS = True
if volume_speed.volume_type == "gp2":
if (volume_speed.size < 170):
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps)","value": 128})
if (volume_speed.size > 170 and volume_speed.size < 334):
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps) ** (if burst credits are available)","value": 250})
if (volume_speed.size > 334):
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps)","value": 250})
if volume_speed.volume_type == "io2" or volume_speed.volume_type == "io1":
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps)","value": 1000})
if volume_speed.volume_type == "st1":
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps)","value": 500})
flagForIOPS = False
if volume_speed.volume_type == "sc1":
new_widget['properties']['annotations']['horizontal'].append({"label": "Maximum Throughput (MBps)","value": 250})
flagForIOPS = False
if volume_speed.volume_type == "gp3":
try:
throughput = volume_speed.throughput
except AttributeError:
throughput = 125
new_widget['properties']['annotations']['horizontal'].append({"label": "Baseline Throughput (MBps)","value": throughput})
widgets['widgets'].append(new_widget)
iopsValue = 0
if bool(flagForIOPS):
if(volume_speed.iops is not None):
iopsValue = volume_speed.iops
else:
iopsValue = 0
else:
iopsValue = 0
# Volume IOPS
new_widget = {
"type": "metric",
"width": 12,
"properties": {
"metrics": [
[ { "expression": "SUM(METRICS('volume'))/PERIOD(volumeReadOps)", "label": "Total IOPS (Operations Per Second)", "id": "totalIOPS", "stat": "Sum", "period": 300 } ],
[ "AWS/EBS", "VolumeWriteOps", "VolumeId", volume, { "visible": False, "id": "volumeWriteOps", "period": 300 } ],
[ "AWS/EBS", "VolumeReadOps", "VolumeId", volume, { "visible": False, "id": "volumeReadOps" , "period": 300} ]
],
"view": "timeSeries",
"stacked": False,
"region": region,
"stat": "Sum",
"period": 300,
"yAxis": {
"left": {
"showUnits": False,
"label": "IOPS"
},
"right": {
"showUnits": False
}
},
"title": "IOPS" + "(" + volume +")",
"annotations": {
"horizontal": [
{
"label": "Baseline performance - IOPS",
"value": iopsValue
}
]
}
}
}
if volume_speed.volume_type == "gp2":
new_widget['properties']['annotations']['horizontal'].append({"label": "Burst IOPS","value": 3000})
if volume_speed.volume_type == "gp3" and iopsValue != 3000:
new_widget['properties']['annotations']['horizontal'].append({"label": "Burst IOPS","value": 3000})
widgets['widgets'].append(new_widget)
number += 1
dashboard = {"periodOverride": "inherit", "widgets": widgets['widgets']}
result = cw.put_dashboard(DashboardName=CloudWatch_DashboardName,DashboardBody=json.dumps(dashboard))
if 'ResponseMetadata' in result:
if 'HTTPStatusCode' in result['ResponseMetadata']:
if result['ResponseMetadata']['HTTPStatusCode'] == 200:
print(f'Dashboard successfully created. \nLink to the dashboard: https://console.aws.amazon.com/cloudwatch/home?region={region}#dashboards:name={CloudWatch_DashboardName}')
else:
print("error with request")