Skip to content

Instantly share code, notes, and snippets.

@ewdurbin
Last active September 18, 2018 20:59
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ewdurbin/0cef98ed3253a7b47b120ecabc878387 to your computer and use it in GitHub Desktop.
Save ewdurbin/0cef98ed3253a7b47b120ecabc878387 to your computer and use it in GitHub Desktop.
Little bit of magic to send your DataDog dogstatsd metrics to CloudWatch

DataDog + CloudWatch Custom Metrics

A little bit of python to take your custom dogstatsd metrics and ship them to CloudWatch :)

Just add the plugin code, configure it as a custom_emitter in DataDog's config then tag your metrics with cloudwatch:emit.

Edit: Also realized you need to add boto3 to dd-agent's venv:

  • sudo /opt/datadog-agent/embedded/bin/pip install boto3

Now your application-level metric can be used to trigger things like AutoScalingRules!

import datetime
import os
import boto3
REGION = os.environ.get('REGION', 'us-east-1')
cloudwatch = boto3.client('cloudwatch', region_name=REGION)
def parse_tags(tag_string):
tags = {}
for tag in filter(None, tag_string.split(', ')):
k, v = tag.replace('"', '').strip().partition(":")[::2]
if v == '':
tags['data_dog_tags'] = tags.get('data_dog_tags', []) + [k]
else:
tags[k] = v
return tags
def send_series_to_cloudwatch(namespace, series, tags):
metric_data = []
for point in series['points']:
data = {
'MetricName': series['metric'],
'Dimensions': [
{
'Name': 'AutoScalingGroupName',
'Value': tags['autoscaling_group']
},
],
'Timestamp': datetime.datetime.utcfromtimestamp(int(point[0])),
'Value': float(point[1])
}
metric_data.append(data)
data = {
'MetricName': series['metric'],
'Dimensions': [
{
'Name': 'InstanceId',
'Value': tags['instance_id']
},
{
'Name': 'AutoScalingGroupName',
'Value': tags['autoscaling_group']
},
],
'Timestamp': datetime.datetime.utcfromtimestamp(int(point[0])),
'Value': float(point[1])
}
metric_data.append(data)
cloudwatch.put_metric_data(
Namespace=namespace,
MetricData=metric_data
)
class CloudWatchEmitter(object):
def __call__(self, payload, logger, config):
agent_tags = parse_tags(config.get('tags', ''))
for series in payload.get('series', []):
series_tags = series.get('tags')
if series_tags is None:
series_tags = []
if 'cloudwatch:emit' in series_tags:
send_series_to_cloudwatch(agent_tags.get('app_name',
'datadog'),
series, agent_tags)
# Write this to /usr/share/datadog/cloudwatch_emitter.py Add a line like:
custom_emitters: /usr/share/datadog/cloudwatch_emitter.py:CloudWatchEmitter'
Simplified BSD License
Copyright (c) 2016-2017, Ernest W. Durbin III
Copyright (c) 2016-2017, The Groundwork LLC.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment