[Twisted-Python] Klein?

Is this the right place to ask klein questions? I'm writing a metrics plugin for Klein and I can't figure out how to inject a metrics handler so that I can get route, path, duration, and status code. What I'm doing now sucks because Klein and twisted interact in complex ways on Failure and status codes.
# Replace the klein _call with the metrics generating call _app._call = _callWithMetrics
Rather than replace _call with my version of _call I was hoping there was a cleaner way to get the start and stop with the result code of a route invocation. Thoughts?

I've used decorators that execute the route function and then fire a call back at the end. Here's a quick example of "metrics at the start of a request and at the end.
``` from functools import wraps from random import randint import time
from klein import Klein from twisted.internet import defer, reactor
def startMetric(f): @wraps(f) def deco(*args, **kw): req = args[1] print(f"[x] start:{time.time()} path:{req.path.decode('utf8')}") result = defer.maybeDeferred(f, *args, **kw) result.addBoth(endMetric, req) return result return deco
def endMetric(result, req): print(f"[x] end:{time.time()} path:{req.path.decode('utf8')} status:{req.code}") return result
class MyApp:
rtr = Klein()
@rtr.route("/hello") @startMetric def hello(self, req): d = defer.Deferred() delay = randint(1, 5) reactor.callLater(delay, d.callback, f"delay:{delay}") req.setResponseCode(403, b"whoopsie") return d
def main(): app = MyApp() app.rtr.run("localhost", 9999)
main() ```
On Mon, Mar 1, 2021, 15:52 Robert DiFalco robert.difalco@gmail.com wrote:
Is this the right place to ask klein questions? I'm writing a metrics plugin for Klein and I can't figure out how to inject a metrics handler so that I can get route, path, duration, and status code. What I'm doing now sucks because Klein and twisted interact in complex ways on Failure and status codes.
# Replace the klein _call with the metrics generating call _app._call = _callWithMetrics
Rather than replace _call with my version of _call I was hoping there was a cleaner way to get the start and stop with the result code of a route invocation. Thoughts?
Twisted-Python mailing list Twisted-Python@twistedmatrix.com https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

On Mar 1, 2021, at 12:51 PM, Robert DiFalco robert.difalco@gmail.com wrote:
Is this the right place to ask klein questions?
Absolutely, it's a Twisted org project.
I'm writing a metrics plugin for Klein and I can't figure out how to inject a metrics handler so that I can get route, path, duration, and status code. What I'm doing now sucks because Klein and twisted interact in complex ways on Failure and status codes. # Replace the klein _call with the metrics generating call _app._call = _callWithMetrics Rather than replace _call with my version of _call I was hoping there was a cleaner way to get the start and stop with the result code of a route invocation. Thoughts?
It sounds like you should contribute a patch that makes this an explicitly-supported pluggable entrypoint, rather than relying on a hack. No need to figure out a way to make it work with existing versions, the magic of open source is that you can change it :).
Feel free to ping here when it's done to remind folks to do a review.
-g

Thanks! The trick will be figuring out how to handle Python exception vs werkzeug exception, and the branched, error handling routes etc. Currently this is the sort of data structure I'm posting to Data Dog. But I can make it a pluggable observer-type idiom so anything can receive these metrics.
tags=[ "path:{}.{}.{}".format(module, className, method), "blocking:{}".format(isBlocking), "module:{}".format(module), "class:{}".format(className), "method:{}".format(method), "status_code:{}".format(request_code), "status_code_class:{}xx".format(status_code_class), ] metrics.timing("my.rest.endpoint", elapsed, tags=tags)
I don't have it quite right yet. It's hard to get the status code, deal with unhandled exceptions, etc. But I'll post questions here when I'm closer.
On Wed, Mar 3, 2021 at 11:13 PM Glyph glyph@twistedmatrix.com wrote:
On Mar 1, 2021, at 12:51 PM, Robert DiFalco robert.difalco@gmail.com wrote:
Is this the right place to ask klein questions?
Absolutely, it's a Twisted org project.
I'm writing a metrics plugin for Klein and I can't figure out how to inject a metrics handler so that I can get route, path, duration, and status code. What I'm doing now sucks because Klein and twisted interact in complex ways on Failure and status codes.
# Replace the klein _call with the metrics generating call _app._call = _callWithMetrics
Rather than replace _call with my version of _call I was hoping there was a cleaner way to get the start and stop with the result code of a route invocation. Thoughts?
It sounds like you should contribute a patch that makes this an explicitly-supported pluggable entrypoint, rather than relying on a hack. No need to figure out a way to make it work with existing versions, the magic of open source is that you can change it :).
Feel free to ping here when it's done to remind folks to do a review.
-g _______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com https://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python

On Mar 4, 2021, at 9:01 PM, Robert DiFalco robert.difalco@gmail.com wrote:
Thanks! The trick will be figuring out how to handle Python exception vs werkzeug exception, and the branched, error handling routes etc. Currently this is the sort of data structure I'm posting to Data Dog. But I can make it a pluggable observer-type idiom so anything can receive these metrics.
tags=[ "path:{}.{}.{}".format(module, className, method), "blocking:{}".format(isBlocking), "module:{}".format(module), "class:{}".format(className), "method:{}".format(method), "status_code:{}".format(request_code), "status_code_class:{}xx".format(status_code_class), ] metrics.timing("my.rest.endpoint", elapsed, tags=tags) I don't have it quite right yet. It's hard to get the status code, deal with unhandled exceptions, etc. But I'll post questions here when I'm closer.
Nifty. Thanks for working on this. I look forward to your PR!
-g
participants (3)
-
Glyph
-
Noman Sarker
-
Robert DiFalco