Created
April 17, 2018 15:51
-
-
Save adamstauffer/fb911274401cf5c59e648583b47ba0f9 to your computer and use it in GitHub Desktop.
Convert AWS Cloudwatch metric alarms into Grafana graph panels with alerts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Generate Grafana graph panels from Cloudwatch Metric Alarms. | |
Meant for alarms that send SNS notifications. Only supports single | |
dimension Cloudwatch alarms. | |
""" | |
import json | |
import boto3 | |
# enter the partial name of an SNS notification to filter alarm actions | |
NOTIFICATION_NAME = '' | |
# name of your cloudwatch datasource in grafana | |
GRAFANA_CLOUDWATCH_DATASOURCE = 'Cloudwatch' | |
# region like 'us-east-1' | |
METRICS_REGION = 'us-east-1' | |
# grafana notification internal ID | |
NOTIFICATION_ID = 1 | |
client = boto3.client('cloudwatch') | |
paginator = client.get_paginator('describe_alarms') | |
page_iterator = paginator.paginate() | |
for page in page_iterator: | |
for metric_alarm in page['MetricAlarms']: | |
# naive way to filter a cloudwatch alarm with an applicable action | |
for alarm_action in metric_alarm['AlarmActions']: | |
if NOTIFICATION_NAME in alarm_action: | |
alarm_name = metric_alarm.get('AlarmName') | |
metric_name = metric_alarm.get('MetricName') | |
namespace = metric_alarm.get('Namespace') | |
statistic = metric_alarm.get('Statistic') | |
threshold = metric_alarm.get('Threshold') | |
# convert cloudwatch comparison to grafana comparison | |
comparison_operator = metric_alarm.get('ComparisonOperator') | |
if 'GreaterThan' in comparison_operator: | |
comparison = 'gt' | |
if 'LessThan' in comparison_operator: | |
comparison = 'lt' | |
# convert evaluation periods & period to evaluation time | |
evaluation_periods = metric_alarm.get('EvaluationPeriods') | |
period = metric_alarm.get('Period') | |
evaluation_time = '{}s'.format(evaluation_periods * period) | |
# only support a single dimension | |
dimensions = metric_alarm['Dimensions'] | |
if len(dimensions) == 0: | |
print( | |
'Could not convert alarm "{}", ' | |
'no dimensions found!'.format(alarm_name)) | |
break | |
dimension = dimensions[0] | |
dimension_name = dimension.get('Name') | |
dimension_value = dimension.get('Value') | |
panel_json = { | |
"alert": { | |
"conditions": [ | |
{ | |
"evaluator": { | |
"params": [ | |
threshold, | |
], | |
"type": comparison, | |
}, | |
"operator": { | |
"type": "and", | |
}, | |
"query": { | |
"params": [ | |
"A", | |
evaluation_time, | |
"now", | |
], | |
}, | |
"reducer": { | |
"params": [], | |
"type": "avg", | |
}, | |
"type": "query", | |
}, | |
], | |
"frequency": "60s", | |
"handler": 1, | |
"message": "", | |
"name": alarm_name, | |
"noDataState": "ok", | |
"notifications": [ | |
{ | |
"id": NOTIFICATION_ID, | |
}, | |
], | |
}, | |
"aliasColors": {}, | |
"bars": False, | |
"dashes": False, | |
"datasource": GRAFANA_CLOUDWATCH_DATASOURCE, | |
"fill": 1, | |
"id": 10, | |
"legend": { | |
"alignAsTable": True, | |
"avg": False, | |
"current": True, | |
"max": False, | |
"min": False, | |
"rightSide": True, | |
"show": True, | |
"total": False, | |
"values": True, | |
}, | |
"lines": True, | |
"linewidth": 1, | |
"links": [], | |
"nullPointMode": "connected", | |
"percentage": False, | |
"pointradius": 5, | |
"points": False, | |
"renderer": "flot", | |
"seriesOverrides": [], | |
"spaceLength": 10, | |
"stack": False, | |
"steppedLine": False, | |
"targets": [ | |
{ | |
"alias": "", | |
"dimensions": { | |
dimension_name: dimension_value, | |
}, | |
"metricName": metric_name, | |
"namespace": namespace, | |
"period": "", | |
"refId": "A", | |
"region": METRICS_REGION, | |
"statistics": [ | |
statistic, | |
], | |
}, | |
], | |
"thresholds": [], | |
"timeFrom": None, | |
"timeShift": None, | |
"title": alarm_name, | |
"tooltip": { | |
"shared": True, | |
"sort": 0, | |
"value_type": "individual", | |
}, | |
"type": "graph", | |
"xaxis": { | |
"buckets": None, | |
"mode": "time", | |
"name": None, | |
"show": True, | |
"values": [], | |
}, | |
"yaxes": [ | |
{ | |
"format": "none", | |
"label": None, | |
"logBase": 1, | |
"max": None, | |
"min": None, | |
"show": True, | |
}, | |
{ | |
"format": "short", | |
"label": None, | |
"logBase": 1, | |
"max": None, | |
"min": None, | |
"show": True, | |
}, | |
], | |
} | |
print(json.dumps(panel_json)) | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment