Skip to content

Commit a9ae378

Browse files
mmoyabrian-brazil
authored andcommitted
Add support for exporting metrics to a pushgateway
1 parent 93654f3 commit a9ae378

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,22 @@ write_to_textfile('/configured/textfile/path/raid.prom', registry)
246246
A separate registry is used, as the default registry may contain other metrics
247247
such as those from the Process Collector.
248248

249+
## Exporting to a Pushgateway
250+
251+
The [Pushgateway](https://github.com/prometheus/pushgateway)
252+
allows ephemeral and batch jobs to expose their metrics to Prometheus.
253+
254+
```python
255+
from prometheus_client import CollectorRegistry,Gauge,push_to_gateway
256+
registry = CollectorRegistry()
257+
g = Gauge('job_last_success_unixtime', 'Last time a batch job successfully finished', registry=registry)
258+
g.set_to_current_time()
259+
push_to_gateway(registry, job='batchA')
260+
```
261+
262+
A separate registry is used, as the default registry may contain other metrics
263+
such as those from the Process Collector.
264+
249265
## Bridges
250266

251267
It is also possible to expose metrics to systems other than Prometheus.

prometheus_client/__init__.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
from . import exposition
55
from . import process_collector
66

7+
try:
8+
from urllib2 import urlopen, quote
9+
except ImportError:
10+
# Python 3
11+
from urllib.request import urlopen
12+
from urllib.parse import quote
13+
14+
715
__all__ = ['Counter', 'Gauge', 'Summary', 'Histogram']
816
# http://stackoverflow.com/questions/19913653/no-unicode-in-all-for-a-packages-init
917
__all__ = [n.encode('ascii') for n in __all__]
@@ -22,6 +30,38 @@
2230
start_http_server = exposition.start_http_server
2331
write_to_textfile = exposition.write_to_textfile
2432

33+
34+
def build_pushgateway_url(job, instance=None, host='localhost', port=9091):
35+
'''
36+
Build a valid pushgateway url
37+
'''
38+
39+
if instance:
40+
instancestr = '/instances/{}'.format(instance)
41+
else:
42+
instancestr = ''
43+
44+
url = 'http://{}:{}/metrics/jobs/{}{}'.format(host, port,
45+
quote(job),
46+
quote(instancestr))
47+
return url
48+
49+
50+
def push_to_gateway_url(url, registry, timeout=None):
51+
'''Push metrics to the given url'''
52+
53+
resp = urlopen(url, data=generate_latest(registry), timeout=timeout)
54+
if resp.code >= 400:
55+
raise IOError("error pushing to pushgateway: {0} {1}".format(
56+
resp.code, resp.msg))
57+
58+
59+
def push_to_gateway(registry, job, instance=None, host='localhost', port=9091, timeout=None):
60+
'''Push metrics to a pushgateway'''
61+
62+
url = build_pushgateway_url(job, instance, host, port)
63+
push_to_gateway_url(url, registry, timeout)
64+
2565
ProcessCollector = process_collector.ProcessCollector
2666
PROCESS_COLLECTOR = process_collector.PROCESS_COLLECTOR
2767

tests/test_client.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from prometheus_client import Gauge, Counter, Summary, Histogram, Metric
77
from prometheus_client import CollectorRegistry, generate_latest, ProcessCollector
8+
from prometheus_client import build_pushgateway_url
89

910

1011
class TestCounter(unittest.TestCase):
@@ -372,6 +373,24 @@ def test_working_fake_pid(self):
372373
self.assertEqual(None, self.registry.get_sample_value('process_fake_namespace'))
373374

374375

376+
class TestBuildPushgatewayUrl(unittest.TestCase):
377+
def test_job_instance(self):
378+
expected = 'http://localhost:9091/metrics/jobs/foojob/instances/fooinstance'
379+
380+
url = build_pushgateway_url('foojob', 'fooinstance')
381+
self.assertEqual(url, expected)
382+
383+
def test_host_port(self):
384+
expected = 'http://foohost:9092/metrics/jobs/foojob'
385+
386+
url = build_pushgateway_url('foojob', host='foohost', port=9092)
387+
self.assertEqual(url, expected)
388+
389+
def test_url_escaping(self):
390+
expected = 'http://localhost:9091/metrics/jobs/foo%20job'
391+
392+
url = build_pushgateway_url('foo job')
393+
self.assertEqual(url, expected)
375394

376395

377396
if __name__ == '__main__':

0 commit comments

Comments
 (0)