Twisted Support¶
The Twisted-related APIs can be found within the prometheus_async.tx package.
Decorator Wrappers¶
- prometheus_async.tx.time(metric: Observer) Callable[[Callable[[P], T | Deferred[T]]], Callable[[P], T | Deferred[T]]]¶
- prometheus_async.tx.time(metric: Observer, deferred: Deferred[T]) Deferred[T]
Call
metric.observe(time)with runtime in seconds.Can be used as a decorator as well as on
Deferreds.Works with both sync and async results.
The fact it’s accepting Deferreds is useful in conjunction with twisted.web views that don’t allow to return a Deferred:
from prometheus_client import Histogram
from prometheus_async.tx import time
from twisted.internet.task import deferLater
from twisted.web.resource import Resource
from twisted.web.server import NOT_DONE_YET
from twisted.internet import reactor
REQ_TIME = Histogram("req_time_seconds", "time spent in requests")
class DelayedResource(Resource):
def _delayedRender(self, request):
request.write("<html><body>Sorry to keep you waiting.</body></html>")
request.finish()
def render_GET(self, request):
d = deferLater(reactor, 5, lambda: request)
time(REQ_TIME, d.addCallback(self._delayedRender))
return NOT_DONE_YET
- prometheus_async.tx.count_exceptions(metric: Incrementer, *, exc: type[BaseException] = <class 'BaseException'>) Callable[[Callable[[P], T]], Callable[[P], T]]¶
- prometheus_async.tx.count_exceptions(metric: ~prometheus_async.types.Incrementer, deferred: ~twisted.internet.defer.Deferred[~prometheus_async.types.T], *, exc: type[BaseException] = <class 'BaseException'>) Deferred[T]
Call
metric.inc()whenever exc is caught.Can be used as a decorator or on a
Deferred.
- prometheus_async.tx.track_inprogress(metric: Gauge) Callable[[Callable[[P], T]], Callable[[P], T]]¶
- prometheus_async.tx.track_inprogress(metric: Gauge, deferred: Deferred[T]) Deferred[T]
Call
metrics.inc()on entry andmetric.dec()on exit.Can be used as a decorator or on a
Deferred.- Returns:
function (if decorator) or
Deferred.- Return type:
Deferred[T] | Callable[[Callable[P, T]], Callable[P, T]]
Metric Exposure¶
prometheus_client, the underlying Prometheus client library, exposes a twisted.web.resource.Resource – namely prometheus_client.twisted.MetricsResource – that makes it extremely easy to expose your metrics.
from prometheus_client.twisted import MetricsResource
from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor
root = Resource()
root.putChild(b"metrics", MetricsResource())
factory = Site(root)
reactor.listenTCP(8000, factory)
reactor.run()
As a slightly more in-depth example, the following exposes the application’s metrics under /metrics and sets up a prometheus_client.Counter for inbound HTTP requests.
It also uses Klein to set up the routes instead of relying directly on twisted.web for routing.
from prometheus_client.twisted import MetricsResource
from twisted.web.server import Site
from twisted.internet import reactor
from klein import Klein
from prometheus_client import Counter
INBOUND_REQUESTS = Counter(
"inbound_requests_total",
"Counter (int) of inbound http requests",
["endpoint", "method"]
)
app = Klein()
@app.route("/metrics")
def metrics(request):
INBOUND_REQUESTS.labels("/metrics", "GET").inc()
return MetricsResource()
factory = Site(app.resource())
reactor.listenTCP(8000, factory)
reactor.run()