Giter Club home page Giter Club logo

python-flask's Introduction

Flask-OpenTracing

Note: This package is no longer maintained or supported. Migrate your application to use opentelemetry-api.

This package enables distributed tracing in Flask applications via The OpenTracing Project. Once a production system contends with real concurrency or splits into many services, crucial (and formerly easy) tasks become difficult: user-facing latency optimization, root-cause analysis of backend errors, communication about distinct pieces of a now-distributed system, etc. Distributed tracing follows a request on its journey from inception to completion from mobile/browser all the way to the microservices.

As core services and libraries adopt OpenTracing, the application builder is no longer burdened with the task of adding basic tracing instrumentation to their own code. In this way, developers can build their applications with the tools they prefer and benefit from built-in tracing instrumentation. OpenTracing implementations exist for major distributed tracing systems and can be bound or swapped with a one-line configuration change.

If you want to learn more about the underlying python API, visit the python source code.

If you are migrating from the 0.x series, you may want to read the list of breaking changes.

Installation

Run the following command:

$ pip install Flask-Opentracing

Usage

This Flask extension allows for tracing of Flask apps using the OpenTracing API. All that it requires is for a FlaskTracing tracer to be initialized using an instance of an OpenTracing tracer. You can either trace all requests to your site, or use function decorators to trace certain individual requests.

Note: optional_args in both cases are any number of attributes (as strings) of flask.Request that you wish to set as tags on the created span

Initialize

FlaskTracing wraps the tracer instance that's supported by opentracing. To create a FlaskTracing object, you can either pass in a tracer object directly or a callable that returns the tracer object. For example:

import opentracing
from flask_opentracing import FlaskTracing

opentracing_tracer = ## some OpenTracing tracer implementation
tracing = FlaskTracing(opentracing_tracer, ...)

or

import opentracing
from flask_opentracing import FlaskTracing

def initialize_tracer():
    ...
    return opentracing_tracer

tracing = FlaskTracing(initialize_tracer, ...)

Trace All Requests

import opentracing
from flask_opentracing import FlaskTracing

app = Flask(__name__)

opentracing_tracer = ## some OpenTracing tracer implementation
tracing = FlaskTracing(opentracing_tracer, True, app, [optional_args])

Trace Individual Requests

import opentracing
from flask_opentracing import FlaskTracing

app = Flask(__name__)

opentracing_tracer = ## some OpenTracing tracer implementation
tracing = FlaskTracing(opentracing_tracer)

@app.route('/some_url')
@tracing.trace(optional_args)
def some_view_func():
    ...
    return some_view

Accessing Spans Manually

In order to access the span for a request, we've provided an method FlaskTracing.get_span(request) that returns the span for the request, if it is exists and is not finished. This can be used to log important events to the span, set tags, or create child spans to trace non-RPC events. If no request is passed in, the current request will be used.

Tracing an RPC

If you want to make an RPC and continue an existing trace, you can inject the current span into the RPC. For example, if making an http request, the following code will continue your trace across the wire:

@tracing.trace()
def some_view_func(request):
    new_request = some_http_request
    current_span = tracing.get_span(request)
    text_carrier = {}
    opentracing_tracer.inject(span, opentracing.Format.TEXT_MAP, text_carrier)
    for k, v in text_carrier.iteritems():
        new_request.add_header(k,v)
    ... # make request

Examples

See examples to view and run an example of two Flask applications with integrated OpenTracing tracers.

This tutorial has a step-by-step guide for using Flask-Opentracing with Jaeger.

Breaking changes from 0.x

Starting with the 1.0 version, a few changes have taken place from previous versions:

  • FlaskTracer has been renamed to FlaskTracing, although FlaskTracing can be used still as a deprecated name.
  • When passing an Application object at FlaskTracing creation time, trace_all_requests defaults to True.
  • When no opentracing.Tracer is provided, FlaskTracing will rely on the global tracer.

Further Information

If you're interested in learning more about the OpenTracing standard, please visit opentracing.io or join the mailing list. If you would like to implement OpenTracing in your project and need help, feel free to send us a note at [email protected].

python-flask's People

Contributors

bensigelman avatar bhs avatar carlosalberto avatar gravelg avatar itsderek23 avatar jamim avatar jan25 avatar kcamenzind avatar kevinjqiu avatar prat0318 avatar ptmcg avatar rmfitzpatrick avatar ror6ax avatar zgfh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-flask's Issues

Running flasktracing in gunicorn ends up to no root span

I have an flask app using flasktracing, all the requests are shown in my jaeger backend UI without WSGI server. But when I run with gunicorn, I saw my "no-root-span" messages in the UI. I am using threads only with only one sync worker, and I have tried lazy-init and normal init the global tracer . Any idea how to fix it?

Still remainders of mock

To complete the clean-up of the separate mock module you forgot few lines:

---
 setup.py                    |    1 -
 tests/test_flask_api.py     |    2 +-
 tests/test_flask_tracing.py |    2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

--- a/setup.py
+++ b/setup.py
@@ -30,7 +30,6 @@ setup(
         'tests': [
             'flake8',
             'flake8-quotes',
-            'mock',
             'pytest',
             'pytest-cov',
         ],
--- a/tests/test_flask_api.py
+++ b/tests/test_flask_api.py
@@ -1,6 +1,6 @@
-import mock
 import pytest
 import unittest
+from unittest import mock
 
 import opentracing
 from flask import Flask
--- a/tests/test_flask_tracing.py
+++ b/tests/test_flask_tracing.py
@@ -1,5 +1,5 @@
-import mock
 import unittest
+from unittest import mock
 
 from flask import (Flask, request)
 import opentracing

Include additional data

The traces are currently pretty minimal, for instance they don't include obvious headers like the remote IP. Is there a way to write one function to collect additional data from the requests, and have it used on all flask routes? I see with https://github.com/opentracing/opentracing-python#inbound-request for example I can make a server wrapper that appends the additional data, but that requires wrapping each route. Is there anyway to get additional request data without wrapping each route individually?

`start_span` on `FlaskTracer` should delegate to the underlying tracer implementation

I'm trying to manually add a span to a trace using the jaeger Python client, as described in the documentation. However in the example, the span is created by calling the underlying tracer implementation directly (jaeger_tracer.start_span() rather than the FlaskTracer instance.

I didn't notice this initially and attempted to call start_span() on my FlaskTracer instance directly, which resulted in an error being raised from the underlying opentracing.Tracer:

Traceback (most recent call last):
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 2301, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 2287, in wsgi_app
    response = self.handle_exception(e)
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 1733, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 2284, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 1807, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 1710, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 1805, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/flask/app.py", line 1791, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/jscn/work/ent-admin/entadmin/api/people/people.py", line 23, in read
    person = PersonRepository().me()
  File "/home/jscn/work/ent-admin/entadmin/repositories/person.py", line 17, in me
    person = self._get_one()
  File "/home/jscn/work/ent-admin/entadmin/repositories/_base.py", line 80, in _get_one
    response = self._get(url)
  File "/home/jscn/work/ent-admin/entadmin/repositories/_base.py", line 68, in _get
    with tracer.start_span('client get', child_of=parent_span) as span:
  File "/home/jscn/venvs/ent-admin/lib/python3.4/site-packages/opentracing/tracer.py", line 88, in start_span
    return self._noop_span
AttributeError: 'Tracer' object has no attribute '_noop_span'```

So it looks like, in order to make this work, I need to always pass around both the FlaskTracer instance, and the underlying jaeger_client.Tracer instance.

Since FlaskTracer already has a reference to that jaeger_client.Tracer instance, and that instance's implementation of start_span actually works, I think that FlaskTracer should delegate calls to start_span to whichever Tracer is passed in when FlaskTracer is instantiated.

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.

scope_manager not accessable via opentracing

In the opentracing API the scope manager is stored in the property _scope_manager and can be accessed as scope_manager.
Currently, the property _scope_manager is not set in the FlaskTracing class. This leads to issues with opentracing instrumentation that needs access to it, e.g. the boto3 part of the https://github.com/uber-common/opentracing-python-instrumentation. (When I have more time, I will try to add a minimal example where failures actually occur.)

I could imagine two fixes to this a) adding

@property 
def _scope_manager(self):
    return self.tracer._scopemanager

or b) explicitly doing:

self._scope_manager = self.tracer.scope_manager

in the initializer.
Happy to write the PR for this, if you provide me your preferences ๐Ÿ™‚

How to exclude certain routes

The example setup works well, however I'm trying to figure out if it's possible to use an exclusion filter to remove http routes I don't want tracing on. For example, /health endpoints are not interesting to get tracing info on.

It this possible?

opentracing setup version

Hi,

opentracing 1.3 can run on python 3, 1.2 and below he can't.

In the setup, 'opentracing>=1.1,<1.2' can be upgrade or there is some issue?

Regards,

Recursive tracing

We have a recursive route we're using for testing, when using the python aws xray tracing here: https://github.com/aws/aws-xray-sdk-python

It includes all depth in the traces. However with the python-flask opentracing module, it's only showing one level of recursion in the waterfall graph. Is there anyway to get more detail?

This is my config:

    config = jaeger_client.Config(config={'sampler': {'type': 'const', 'param': 1}, 
                            'logging': True,
                            'local_agent':
                            {'reporting_host': JAEGER_HOST}},
                    service_name="jaeger_opentracing_example")
    jaeger_tracer = config.initialize_tracer()
    # This will trace all requests; routes can also be chosen individually instead
    # Traced attributes lists additional request attributes we want to capture
    tracing = FlaskTracing(jaeger_tracer, True, app, traced_atrributes=['remote_addr'])

Here is the flask route:

@app.route("/recurse/<number>", methods=['GET'])
def recurse(number):
    '''Recursively call itself with sleep'''
    num = int(number)
    if num> 0:
        val = num - 1
        sleep((randint(200,600)/1000.0))
        r = requests.get("http://turquoise.default/recurse/%d" % val)
        string = "%sAt depth %d!<br>" % (r.text, num)
        return string, r.status_code
    else:
        return "Depth 0!", 200

For instance calling /recurse/7 results in the following waterfalls:

Screenshot from 2019-05-15 08-54-34
Screenshot from 2019-05-15 08-54-43

Question: How use opentracing.global_tracer() when using jaeger_client lib

This example https://github.com/opentracing-contrib/python-flask/blob/master/example/server.py#L28 uses the tracer returned by jaeger_client's initialize_tracer method. This method internally sets the opentracing.tracer to jaeger tracer object, this means for any request handler there after can do opentracing.global_tracer().start_span(...) and this sends traces to jaeger

I noticed when i run a flask dev server(using app.run) opentracing.global_tracer() is not the same as jaeger tracer i initialised earlier(as in the the link above) when starting up the server. Is there something i'm missing on flask side?

I could use returned jaeger_tracer from initialize_tracer(), which would mean i'd have to pass this around or create my own process/request local storage. I suppose according to jaeger tracer docs https://github.com/jaegertracing/jaeger-client-python#production, the initialised jaeger tracer must be available via opentracing.global_tracer()

Status code tag is not added to spans when using @trace decorator

How to reproduce the issue

Let's use whatever tracer (I used jaeger for this example) and use the trace decorator. Ex.:

from flask import Flask
from flask_opentracing import FlaskTracer

app = Flask(__name__)


def initialize_tracer():
    config = Config(
        config={
            'sampler': {'type': 'const', 'param': 1}
        },
        service_name='hello-world'
    )
    return config.initialize_tracer()


flask_tracer = FlaskTracer(initialize_tracer)


@app.route('/')
@flask_tracer.trace()
def hello():
    return 'Hello'

In the resulting span, the HTTP_STATUS_CODE tag should not be present.

Possible cause

Looking at the code, it seems the response is not being passed to the _after_request_fn method when using the trace decorator.

https://github.com/opentracing-contrib/python-flask/blob/master/flask_opentracing/tracing.py#L83

Possible fix

I attached a PR with one possible solution.

Is it possible to use this with jaeger-client 4.0.0?

I'm seeing this error when trying to use this with the latest jaeger-client:

ERROR: jaeger-client 4.0.0 has requirement opentracing<3.0,>=2.1, but you'll have opentracing 2.0.0 which is incompatible.

Are there plans to upgrade this to be compatible?

'Tracer' object has no attribute '_noop_scope'

Following the standard example but calling Flask.run explicitly, like:

       def initialize_tracer():
            from jaeger_client import Config
            config = Config(
                config={
                    'sampler': {'type': 'const', 'param': 1}
                },
                service_name='hello-world')
            return config.initialize_tracer() # also sets opentracing.tracer                                      

        def rest_prediction_server():
            app = seldon_microservice.get_rest_microservice(
                user_object, debug=DEBUG)


            from flask_opentracing import FlaskTracer

            flask_tracer = FlaskTracer(initialize_tracer, True, app)

            app.run(host='0.0.0.0', port=port)

I get on REST call:

Traceback (most recent call last):
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/app.py", line 1811, in full_dispatch_request
    rv = self.preprocess_request()
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask/app.py", line 2087, in preprocess_request
    rv = func()
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask_opentracing/tracing.py", line 39, in start_trace
    self._before_request_fn(traced_attributes)
  File "/home/clive/anaconda3/lib/python3.6/site-packages/flask_opentracing/tracing.py", line 121, in _before_request_fn
    child_of=span_ctx)
  File "/home/clive/anaconda3/lib/python3.6/site-packages/opentracing/tracer.py", line 126, in start_active_span
    return self._noop_scope
AttributeError: 'Tracer' object has no attribute '_noop_scope'

Any ideas?

TestTracingStartSpanCallback tests fail with AssertionError: The setup method 'before_request' can no longer be called on the application.

When packaging 1.1.0 version of the package with Flask 2.3.3 on openSUSE/Tumbleweed, I get the following errors:

[   16s] =================================== FAILURES ===================================
[   16s] ___________________ TestTracingStartSpanCallback.test_error ____________________
[   16s] tests/test_flask_tracing.py:218: in test_error
[   16s]     tracing = FlaskTracing(MockTracer(), True, app,
[   16s] flask_opentracing/tracing.py:38: in __init__
[   16s]     def start_trace():
[   16s] /usr/lib/python3.9/site-packages/flask/scaffold.py:49: in wrapper_func
[   16s]     self._check_setup_finished(f_name)
[   16s] /usr/lib/python3.9/site-packages/flask/app.py:511: in _check_setup_finished
[   16s]     raise AssertionError(
[   16s] E   AssertionError: The setup method 'before_request' can no longer be called on the application. It has already handled its first request, any changes will not be applied consistently.
[   16s] E   Make sure all imports, decorators, functions, etc. needed to set up the application are done before running it.
[   16s] ___________________ TestTracingStartSpanCallback.test_simple ___________________
[   16s] tests/test_flask_tracing.py:204: in test_simple
[   16s]     tracing = FlaskTracing(MockTracer(), True, app,
[   16s] flask_opentracing/tracing.py:38: in __init__
[   16s]     def start_trace():
[   16s] /usr/lib/python3.9/site-packages/flask/scaffold.py:49: in wrapper_func
[   16s]     self._check_setup_finished(f_name)
[   16s] /usr/lib/python3.9/site-packages/flask/app.py:511: in _check_setup_finished
[   16s]     raise AssertionError(
[   16s] E   AssertionError: The setup method 'before_request' can no longer be called on the application. It has already handled its first request, any changes will not be applied consistently.
[   16s] E   Make sure all imports, decorators, functions, etc. needed to set up the application are done before running it.

Complete build log with all packages used and steps taken to reproduce.

Upgrade OT to 2.2.0

Is it safe to upgrade opentracing dependency to 2.2.0?

I'm trying to use jaeger_client latest (4.0.0, which needs opentracing <3.0,>=2.1) in my Flask app. Unfortunately, that won't work because flask-opentracing 1.0.0 requires opentracing<2.1,>=2.0.

On 404 operation_id is None which causes issues with some tracers

The wavefront tracer specifically requires span names be non-None:

ValueError
ValueError: Span name cannot be blank
ValueError
ValueError: Span name cannot be blank

Traceback (most recent call last)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2463, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app
response = self.handle_exception(e)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
return self.finalize_request(rv)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1969, in finalize_request
response = self.process_response(response)
File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 2266, in process_response
response = handler(response)
File "/usr/local/lib/python3.7/site-packages/flask_opentracing/tracing.py", line 43, in end_trace
self._after_request_fn(response)
File "/usr/local/lib/python3.7/site-packages/flask_opentracing/tracing.py", line 160, in _after_request_fn
scope.close()
File "/usr/local/lib/python3.7/site-packages/opentracing/scope_managers/__init__.py", line 77, in close
self.span.finish()
File "/usr/local/lib/python3.7/site-packages/wavefront_opentracing_sdk/span.py", line 165, in finish
self._do_finish(time.time() - self.start_time)
File "/usr/local/lib/python3.7/site-packages/wavefront_opentracing_sdk/span.py", line 191, in _do_finish
self.tracer.report_span(self)
File "/usr/local/lib/python3.7/site-packages/wavefront_opentracing_sdk/tracer.py", line 274, in report_span
self._reporter.report(span)
File "/usr/local/lib/python3.7/site-packages/wavefront_opentracing_sdk/reporting/composite.py", line 32, in report
rep.report(wavefront_span)
File "/usr/local/lib/python3.7/site-packages/wavefront_opentracing_sdk/reporting/console.py", line 35, in report
default_source='unknown')
File "/usr/local/lib/python3.7/site-packages/wavefront_sdk/common/utils.py", line 236, in tracing_span_to_line_data
raise ValueError('Span name cannot be blank')
ValueError: Span name cannot be blank

Is there a mechanism to provide a default name for that case?

How to invoke other services gracefully

I have this code,
@app.route('/') def pull_requests(): url = 'http://localhost:5002/' r = requests.t(url) return r.text
In this service will get a span ,in other service 'http://localhost:5002/' will get a span,
but not in a same track ;
How to invoke other services gracefully?
thk

Possibility to call init_app

Seems like the plugin does not support deferred app initialization like other plugins do.

To avoid any cyclic imports in the app it would be great to have init_app method which takes an app as a parameter. Sometimes it's not that easy to initialize a tracer with modular layout.
The documentation has no mention about the usage with flask app factory pattern.

Example

plugins.py

tracer = FlaskTracer()

app.py

from plugins import tracer

def create_app():
    app = Flask()
    tracer.init_app(app)
    return app

Question: Release Status

What is the status of getting master released? I need the broader opentracing version pinning in order to incorporate this library into my project, and master seems to work in my project, but I would much prefer to install a released package.

Passing around spans and other stories

Hello,

I am working on building an demo application to work out how this whole opentracing story goes together. I have two simple services to make a very basic calculator - Mul and Add.

Whilst I am able to get data from both of these services into Jaeger I am at a loss how I can get the tracing context also passed around so that it joins up in the Jaeger interface. I am expecting to see some of these special headers in the requests but I'm not having any luck.

Could anyone point me in the right direction?

Thanks,

Andrew

Mul

@flask_tracer.trace()
@application.route('/', methods=['GET'])
def mul():
    parent_span = flask_tracer.get_span()
    with opentracing.tracer.start_span('parent-spain', child_of=parent_span) as parent_span:

            headers = { "Content-Type": "application/json", "Accept": "application/json" }
            sum_value = int()
            for x in range(0, request.json[0]):
                with opentracing.tracer.start_span('child-spain', child_of=parent_span) as child_span:
                    calculation = [sum_value, request.json[1]]
                    sum_value = json.loads(
                        requests.get(add_url, json=calculation,  
                            headers=headers).content)
                    child_span.set_tag("Answer", sum_value)
        return Response(json.dumps(sum_value), 200)

Add

@flask_tracer.trace()
@application.route('/', methods=['GET'])
def add():
    current_span = flask_tracer.get_span(request)
    text_carrier = {}
    flask_tracer.inject(current_span, opentracing.Format.TEXT_MAP, text_carrier)
    answer = sum(request.json)
    return Response(json.dumps(answer), 200)

Incompatible with Flask 3.0

Flask-OpenTracing's tracing.py imports a private variable from Flask:

from flask import _request_ctx_stack as stack

This variable was deprecated in Flask 2.4 and was removed in Flask 3.0, released at the end of September, 2023.

Please revise your code to make use of the new supported request, documented here.

does not work when started via flask run

The following script never starts the webserver and just hangs forever:

import opentracing
from flask import Flask
from flask_opentracing import FlaskTracer
from jaeger_client import Config

app = Flask(__name__)

config = Config(
config={ # usually read from some yaml config
                          'sampler': {
                          'type': 'const',
                          'param': 1,
                  },
                          'logging': True,
                  },
service_name='flask_app_1',
)


opentracing_tracer = config.initialize_tracer()
tracer = FlaskTracer(opentracing_tracer)

@app.route('/some_url')
@tracer.trace()
def some_view_func():
    return "some_view"

With debug logging turned on, I see this:

2017-11-06 15:10:16,177 Initializing Jaeger Tracer with UDP reporter

Same script with minimal changes started by python scriptname.py works as a charm.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.