Skip to content

Instantly share code, notes, and snippets.

@ohsawa0515
Last active January 6, 2017 01:35
Show Gist options
  • Save ohsawa0515/03534641aa36b1d4554a8a5fba8076dd to your computer and use it in GitHub Desktop.
Save ohsawa0515/03534641aa36b1d4554a8a5fba8076dd to your computer and use it in GitHub Desktop.
Send CloudWatch metics to Mackerel host metrics using Amazon Lambda.
# -*- coding: utf-8 -*-
import boto3, os, json, calendar
from base64 import b64decode
from datetime import datetime, timedelta
from urllib2 import Request, urlopen
os.environ['TZ'] = 'Asia/Tokyo'
mackerel_url = "https://mackerel.io/api/v0/tsdb"
encrypted_mackerel_api_key = "<ENCRYPTED_API_KEY>"
kms = boto3.client('kms')
api_key = kms.decrypt(CiphertextBlob=b64decode(encrypted_mackerel_api_key))['Plaintext']
def get_metric_value(namespace, metric_name, dimensions, stats, unit):
dm = []
for dimension in dimensions:
dm.append({'Name': dimension["name"], 'Value': dimension["value"]})
print dm
end = datetime.utcnow()
start = end + timedelta(minutes=-30)
client = boto3.client('cloudwatch')
response = client.get_metric_statistics(
Namespace=namespace,
MetricName=metric_name,
Dimensions=dm,
StartTime=start.strftime("%Y-%m-%dT%H:%M:%SZ"),
EndTime=end.strftime("%Y-%m-%dT%H:%M:%SZ"),
Period=60,
Statistics=[
stats,
],
Unit=unit
)
if str(response["ResponseMetadata"]["HTTPStatusCode"]) != "200":
return False
if len(response["Datapoints"]) == 0:
return False
return sorted(response["Datapoints"], key=lambda x:x['Timestamp'], reverse=True)[0]
def build_params(host_id, metric_name, time, value):
return json.dumps(
[{
"hostId": host_id,
"name": metric_name,
"time": time,
"value": value
}]
)
def post_mackerel(url, api_key, params, retry=5, wait=5):
retry_count = 0
response = None
while True:
try:
req = Request(url, params)
req.add_header("X-Api-Key", api_key)
req.add_header("Content-Type", "application/json")
response = urlopen(req)
except Exception, e:
print e
finally:
if response is not None:
if response.getcode() == 200:
return True
retry_count += 1
if retry_count >= retry:
return False
time.sleep(wait)
# main
def lambda_handler(event, context):
for input in event:
mackerel = input['mackerel']
cloudwatch = input['cloudwatch']
url = mackerel_url
metric = get_metric_value(
cloudwatch["namespace"],
cloudwatch["metric_name"],
cloudwatch["dimensions"],
cloudwatch["stats"],
cloudwatch["unit"]
)
if metric is False:
continue
params = build_params(
mackerel["host_id"],
mackerel["metric_name"],
calendar.timegm(metric["Timestamp"].timetuple()),
metric[cloudwatch["stats"]]
)
result = post_mackerel(url, api_key, params)
if result is False:
continue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment