python-flask icon indicating copy to clipboard operation
python-flask copied to clipboard

Best way to trace from inside other classes and static methods

Open trondhindenes opened this issue 6 years ago • 5 comments

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.

trondhindenes avatar May 13 '18 20:05 trondhindenes

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.

ror6ax avatar May 13 '18 20:05 ror6ax

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.

jscn avatar May 31 '18 00:05 jscn

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.

carlosalberto avatar May 31 '18 02:05 carlosalberto

oops

trondhindenes avatar Jun 04 '18 21:06 trondhindenes

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.

trondhindenes avatar Jun 29 '18 09:06 trondhindenes