Last active
September 19, 2016 15:12
-
-
Save wyattjoh/4a8592f5602b6acc9e8a0a0b6c18e8e6 to your computer and use it in GitHub Desktop.
Datadog Prometheus Check
This file contains hidden or 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
from checks import AgentCheck | |
import re | |
import requests | |
rx0 = re.compile(r'^# TYPE \S+ (\S+)$') | |
rx1 = re.compile(r'(\w+)(?:{(\S+)})? ([-+]?\d*\.\d+|\d+)') | |
rx2 = re.compile(r'(\w+)="(\S*?)",?') | |
class PrometheusCheck(AgentCheck): | |
# generates the match pattern to determine if we should submit this metric | |
def get_pattern(self, patterns): | |
if patterns and len(patterns) > 0: | |
valid_patterns = '|'.join(patterns) | |
return re.compile(r'^(?:' + valid_patterns + ')') | |
return False | |
# retrieves the metric function from the given type of prometheus metric | |
def get_metric_func(self, metric_type): | |
# if it's a gauge, we'll use the gauge! | |
if metric_type == 'gauge': return self.gauge | |
# if it's a counter, we'll use count! | |
elif metric_type == 'counter': return self.count | |
# ATM, we aren't concerned with the other values | |
else: return False | |
# implemented as a part of the AgentCheck class | |
def check(self, instance): | |
name = instance['name'] | |
url = instance['url'] | |
pattern = self.get_pattern(instance['patterns']) | |
r = requests.get(url, stream=True) | |
# this is our handle for the function to use to record the metric in | |
# question | |
metric_func = False | |
for line in r.iter_lines(): | |
# skip if there is nothing to process | |
if not line: continue | |
# determine the metric type | |
if line.startswith("#"): | |
m0 = rx0.match(line) | |
if m0: | |
# seems this is a TYPE line, let's see what kind of metric | |
# this is so we can get the function to call to send this | |
# off to dd | |
metric_type = m0.groups()[0] | |
metric_func = self.get_metric_func(metric_type) | |
# regardless, this isn't a data line, so let's restart | |
continue | |
# this is a data line, let's check it out | |
if metric_func: | |
# extract the values from it | |
m1 = rx1.match(line) | |
if m1: | |
g1 = m1.groups() | |
if pattern and not pattern.match(g1[0]): | |
continue | |
# create the metric name from it | |
metric = '{0}.{1}'.format(name, g1[0]) | |
# and parse the float value | |
value = float(g1[2]) | |
# default is no tags | |
tags = None | |
# and if there are tags | |
if g1[1] is not None: | |
# extract them | |
m2 = rx2.findall(g1[1]) | |
# and set them on the tag object | |
tags = ['{0}:{1}'.format(tag[0], tag[1]) for tag in m2] | |
# and record it using the metric func | |
metric_func(metric, value, tags=tags) | |
if __name__ == '__main__': | |
check, instances = PrometheusCheck.from_yaml('/etc/dd-agent/conf.d/prometheus.yaml') | |
for instance in instances: | |
print "\nRunning the check against url: %s" % (instance['url']) | |
check.check(instance) | |
if check.has_events(): | |
print 'Events: %s' % (check.get_events()) | |
print 'Metrics: %s' % (check.get_metrics()) |
This file contains hidden or 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
init_config: | |
min_collection_interval: 20 | |
instances: | |
- url: http://localhost:9180/metrics | |
name: caddy | |
patterns: | |
- http |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment