Skip to content

Calling flask.copy_current_request_context results in error logged from OTEL context.detach/Flask instrumentation #868

Closed
@joshuahlang

Description

@joshuahlang
Flask: 2.0.2
Python: 3.9.8 (main, Nov 10 2021, 09:21:22)  [Clang 13.0.0 (clang-1300.0.29.3)]
OTEL Flask instrumentation: 0.27b0

Steps to reproduce
Install the latest requirements in a venv:

python3 -m venv otel-venv && otel-venv/bin/pip install gevent flask opentelemetry.instrumentation.flask opentelemetry.sdk

Use the following code to create a running Flask application. curl http://localhost:5000/ and not the logged error of Failed to detach context from here.

import sys

import gevent
from gevent.pywsgi import WSGIServer
import flask
from opentelemetry import trace
import opentelemetry.instrumentation.flask
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
from opentelemetry.sdk.trace import TracerProvider


app = flask.Flask(__name__)

tracer_provider = TracerProvider(
    active_span_processor=SimpleSpanProcessor(ConsoleSpanExporter())
)
trace.set_tracer_provider(tracer_provider)

opentelemetry.instrumentation.flask.FlaskInstrumentor().instrument_app(app)


@app.route('/')
def index():
    @flask.copy_current_request_context
    def do_some_work():
        with trace.get_tracer(__name__).start_span('async-work'):
            print('did some async work')

    with trace.get_tracer(__name__).start_span('sync-work'):
        gevent.spawn(do_some_work)
    return '\n'.join(map(
        lambda args: '{}: {}'.format(*args),
        [
            ('Flask', flask.__version__),
            ('Python', sys.version.replace('\n', ' ')),
            ('OTEL Flask instrumentation', opentelemetry.instrumentation.flask.version.__version__),
        ]
    )) + '\n'


http_server = WSGIServer(('', 5000), app)
http_server.serve_forever()

What is the expected behavior?
No Failed to detach context error message logged. I'd expect the async work span(s) to be also have the parent_id set to a span in the originating HTTP request thread of execution (though perhaps my expectation is off on this point).

What is the actual behavior?
The Context logs the following error Failed to detach context from the do_some_work thread of execution when attempting to clean up the context created in the HTTP request handler index

Additional context
Note I originally reproduced this issue in Flask 1.x. It appears the Flask code hasn't changed much in this area so I'd expect any solution would be compatible with Flask 1.x as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions