python-flask
python-flask copied to clipboard
Best way to trace from inside other classes and static methods
This may be a bit too generic question, but I'm attempting it anyway:
It would be awesome if the there was examples of a more "real-life" flask app. As a rule we split up the app into multiple classes (one class per route), and also move "helpers" into separate class functions (static or not).
It's not completely clear to me how I would go about maintining a reference to the instantiated FlaskTracer
object (called tracer
in the examples).
- For route classes we usually "cheat" by importing them after the app object is instantiated, so those can reference the
FlaskTracer
by importing it from the app class - However, for helpers these are usually imported before the app object is instantiated (as a normal import).
I guess I'm looking for best-practices in how to deal the FlaskTracer
throughout my app. Some more advanced examples would be awesome.
Hi @trondhindenes , that's an amazing suggestion! I am in fact in the middle of getting some of my real life micro-services instrumented with this. And there's ongoing effort for more documentation. So both sides of the question should be covered.
Feel free to leave more feedback and contribute your own findings as well.
I'm just toying with adding this to an existing, medium-sized Flask app that uses Blueprints and ran into the same issue. I need to pass the app instance to FlaskTracer
, but want to import the resulting tracer instance in other files (so I can explicitly set up spans for outgoing HTTP reqeusts to un-instrumented services), which are in turn imported by the file containing the create_app
app factory, resulting in a circular import which prevents the application from running.
My solution was to sub-class FlaskTracer
and add a method which does the app setup from FlaskTracer.__init__
(basically the following):
class Tracer(FlaskTracer):
def trace_app(self, app, attributes=None):
if attributes is None:
attributes = []
@app.before_request
def start_trace():
self._before_request_fn(attributes)
@app.after_request
def end_trace(response):
self._after_request_fn()
return response
That allows me to create the tracer separately from the app, and import the tracer into the file which sets up the app (and any other file), without causing any circular imports.
Hey @jscn
Sounds like we need to support some way of late app
initialization (maybe through some helper function). If you have a more complete (but small ;) )example of this case, we can create a new issue in this repo so we track it and work on something that doesn't force you to write a workaround.
oops
Yah, an example app with both flask-tracing and "regular" opentracing components would help so much. I'm still not sure what the best way is to wire all this up.