diff --git a/README.md b/README.md index 97c56f78..5af4cc51 100644 --- a/README.md +++ b/README.md @@ -247,6 +247,32 @@ reactor.listenTCP(8000, factory) reactor.run() ``` +#### WSGI + +To use Prometheus with [WSGI](http://wsgi.readthedocs.org/en/latest/), there is +`make_wsgi_app` which creates a WSGI application. + +```python +from prometheus_client import make_wsgi_app +from wsgiref.simple_server import make_server + +app = make_wsgi_app() +httpd = make_server('', 8000, app) +httpd.serve_forever() +``` + +Such an application can be useful when integrating Prometheus metrics with WSGI +apps. + +The method `start_wsgi_server` can be used to serve the metrics through the +WSGI reference implementation in a new thread. + +```python +from prometheus_client import start_wsgi_server + +start_wsgi_server(8000) +``` + ### Node exporter textfile collector The [textfile collector](https://github.com/prometheus/node_exporter#textfile-collector) diff --git a/prometheus_client/__init__.py b/prometheus_client/__init__.py index 80424dbf..358146a4 100644 --- a/prometheus_client/__init__.py +++ b/prometheus_client/__init__.py @@ -19,7 +19,9 @@ CONTENT_TYPE_LATEST = exposition.CONTENT_TYPE_LATEST generate_latest = exposition.generate_latest MetricsHandler = exposition.MetricsHandler +make_wsgi_app = exposition.make_wsgi_app start_http_server = exposition.start_http_server +start_wsgi_server = exposition.start_wsgi_server write_to_textfile = exposition.write_to_textfile push_to_gateway = exposition.push_to_gateway pushadd_to_gateway = exposition.pushadd_to_gateway diff --git a/prometheus_client/exposition.py b/prometheus_client/exposition.py index 3c4795d3..5470ad7c 100644 --- a/prometheus_client/exposition.py +++ b/prometheus_client/exposition.py @@ -7,6 +7,7 @@ import time import threading from contextlib import closing +from wsgiref.simple_server import make_server from . import core try: @@ -23,10 +24,31 @@ from urllib.parse import quote_plus -CONTENT_TYPE_LATEST = 'text/plain; version=0.0.4; charset=utf-8' +CONTENT_TYPE_LATEST = str('text/plain; version=0.0.4; charset=utf-8') '''Content type of the latest text format''' +def make_wsgi_app(): + '''Create a WSGI app which serves the metrics from the registry.''' + def prometheus_app(environ, start_response): + status = str('200 OK') + headers = [(str('Content-type'), CONTENT_TYPE_LATEST)] + start_response(status, headers) + return [generate_latest(core.REGISTRY)] + return prometheus_app + + +def start_wsgi_server(port, addr=''): + """Starts a WSGI server for prometheus metrics as a daemon thread.""" + class PrometheusMetricsServer(threading.Thread): + def run(self): + httpd = make_server(addr, port, make_wsgi_app()) + httpd.serve_forever() + t = PrometheusMetricsServer() + t.daemon = True + t.start() + + def generate_latest(registry=core.REGISTRY): '''Returns the metrics from the registry in latest text format as a string.''' output = []