diff options
author | Christopher Baines <mail@cbaines.net> | 2015-12-22 17:59:32 +0000 |
---|---|---|
committer | Christopher Baines <mail@cbaines.net> | 2015-12-22 17:59:32 +0000 |
commit | bcc61110d5b76580a2da0d72d07de8efd7525292 (patch) | |
tree | 00d691a550156997acf793d84afc230f00153c3b /prometheus_client/bridge/graphite.py | |
download | python-prometheus-client-upstream.tar python-prometheus-client-upstream.tar.gz |
Import python-prometheus-client_0.0.13.orig.tar.gzupstream-0.0.13upstream
Diffstat (limited to 'prometheus_client/bridge/graphite.py')
-rw-r--r-- | prometheus_client/bridge/graphite.py | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/prometheus_client/bridge/graphite.py b/prometheus_client/bridge/graphite.py new file mode 100644 index 0000000..a01c312 --- /dev/null +++ b/prometheus_client/bridge/graphite.py @@ -0,0 +1,80 @@ +#!/usr/bin/python +from __future__ import unicode_literals + +import logging +import re +import socket +import time +import threading + +from .. import core + +# Roughly, have to keep to what works as a file name. +# We also remove periods, so labels can be distinguished. +_INVALID_GRAPHITE_CHARS = re.compile(r"[^a-zA-Z0-9_-]") + + +def _sanitize(s): + return _INVALID_GRAPHITE_CHARS.sub('_', s) + + +class _RegularPush(threading.Thread): + def __init__(self, pusher, interval, prefix): + super(_RegularPush, self).__init__() + self._pusher = pusher + self._interval = interval + self._prefix = prefix + + def run(self): + wait_until = time.time() + while True: + while True: + now = time.time() + if now >= wait_until: + # May need to skip some pushes. + while wait_until < now: + wait_until += self._interval + break + # time.sleep can return early. + time.sleep(wait_until - now) + try: + self._pusher.push(prefix=self._prefix) + except IOError: + logging.exception("Push failed") + + +class GraphiteBridge(object): + def __init__(self, address, registry=core.REGISTRY, timeout_seconds=30, _time=time): + self._address = address + self._registry = registry + self._timeout = timeout_seconds + self._time = _time + + def push(self, prefix=''): + now = int(self._time.time()) + output = [] + + prefixstr = '' + if prefix: + prefixstr = prefix + '.' + + for metric in self._registry.collect(): + for name, labels, value in metric.samples: + if labels: + labelstr = '.' + '.'.join( + ['{0}.{1}'.format( + _sanitize(k), _sanitize(v)) + for k, v in sorted(labels.items())]) + else: + labelstr = '' + output.append('{0}{1}{2} {3} {4}\n'.format( + prefixstr, _sanitize(name), labelstr, float(value), now)) + + conn = socket.create_connection(self._address, self._timeout) + conn.sendall(''.join(output).encode('ascii')) + conn.close() + + def start(self, interval=60.0, prefix=''): + t = _RegularPush(self, interval, prefix) + t.daemon = True + t.start() |