Skip to content

Commit

Permalink
Add support for tornado.
Browse files Browse the repository at this point in the history
[Resolves #114]

Signed-off-by: Joshua Carp <jm.carp@gmail.com>
  • Loading branch information
jmcarp committed Sep 23, 2018
1 parent 8586b8d commit b8be7c3
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
Expand Up @@ -280,6 +280,29 @@ reactor.listenTCP(8000, factory)
reactor.run()
```

#### Tornado

To use prometheus with [tornado](https://www.tornadoweb.org/), there is `MetricsHandler` which exposes metrics as a tornado handler.

```python
from prometheus_client.tornado import MetricsHandler

import tornado.ioloop
import tornado.web

def make_app():
return tornado.web.Application([
(r"/", MainHandler),
])

if __name__ == "__main__":
app = tornado.web.Application([
(r'/metrics', MetricsHandler)
])
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
```

#### WSGI

To use Prometheus with [WSGI](http://wsgi.readthedocs.org/en/latest/), there is
Expand Down
3 changes: 3 additions & 0 deletions prometheus_client/tornado/__init__.py
@@ -0,0 +1,3 @@
from ._exposition import MetricsHandler

__all__ = ['MetricsHandler']
17 changes: 17 additions & 0 deletions prometheus_client/tornado/_exposition.py
@@ -0,0 +1,17 @@
from __future__ import absolute_import, unicode_literals
from .. import REGISTRY, exposition

import tornado.web


class MetricsHandler(tornado.web.RequestHandler):
"""
Tornado ``Handler`` that serves prometheus metrics.
"""
def initialize(self, registry=REGISTRY):
self.registry = registry

def get(self):
encoder, content_type = exposition.choose_encoder(self.request.headers.get('Accept'))
self.set_header('Content-Type', content_type)
self.write(encoder(self.registry))
2 changes: 2 additions & 0 deletions setup.py
Expand Up @@ -17,9 +17,11 @@
'prometheus_client.bridge',
'prometheus_client.openmetrics',
'prometheus_client.twisted',
'prometheus_client.tornado',
],
extras_require={
'twisted': ['twisted'],
'tornado': ['tornado'],
},
test_suite="tests",
classifiers=[
Expand Down
44 changes: 44 additions & 0 deletions tests/test_tornado.py
@@ -0,0 +1,44 @@
from __future__ import absolute_import, unicode_literals

import sys

if sys.version_info < (2, 7):
from unittest2 import skipUnless
else:
from unittest import skipUnless

from prometheus_client import Counter
from prometheus_client import CollectorRegistry, generate_latest

try:
from prometheus_client.tornado import MetricsHandler

import tornado.ioloop
import tornado.web
import tornado.testing
TestCase = tornado.testing.AsyncHTTPTestCase
HAVE_TORNADO = True
except ImportError:
from unittest import TestCase
HAVE_TORNADO = False


class MetricsResourceTest(TestCase):
def get_app(self):
self.registry = CollectorRegistry()
return tornado.web.Application([
(r'/metrics', MetricsHandler, {'registry': self.registry}),
])

@skipUnless(HAVE_TORNADO, "Don't have tornado installed.")
def test_reports_metrics(self):
"""
``MetricsHandler`` serves the metrics from the provided registry.
"""
c = Counter('cc', 'A counter', registry=self.registry)
c.inc()

resp = self.fetch('/metrics')

self.assertEqual(resp.code, 200)
self.assertEqual(resp.body, generate_latest(self.registry))
1 change: 1 addition & 0 deletions tox.ini
Expand Up @@ -30,6 +30,7 @@ deps =
deps =
{[base]deps}
{py27,py34,py35,py36,pypy}: twisted
{py27,py34,py35,py36,pypy}: tornado
commands = coverage run --parallel -m pytest {posargs}


Expand Down

0 comments on commit b8be7c3

Please sign in to comment.