Skip to content

ext-flask: flask.copy_current_request_context breaks span #267

@kaos

Description

@kaos

Describe your environment
$ python --version
Python 3.7.5

opentelemetry-api 0.3a0
opentelemetry-ext-flask 0.3a0
opentelemetry-ext-jaeger 0.3a0
opentelemetry-ext-wsgi 0.3a0
opentelemetry-sdk 0.3a0

Not fixed in latest master, as of today:
https://github.com/open-telemetry/opentelemetry-python/blob/4458698ea178498f7af2d476644b34afcc366335/ext/opentelemetry-ext-flask/src/opentelemetry/ext/flask/__init__.py#L83

Steps to reproduce

from flask import Flask, copy_current_request_context
from opentelemetry.ext.flask import instrument_app
from opentelemetry import trace
from opentelemetry.context import Context
from opentelemetry.sdk.trace import Tracer
from opentelemetry.sdk.trace.export import ConsoleSpanExporter
from opentelemetry.sdk.trace.export import SimpleExportSpanProcessor

trace.set_preferred_tracer_implementation(lambda T: Tracer())
span_exporter = ConsoleSpanExporter()
trace.tracer().add_span_processor(SimpleExportSpanProcessor(span_exporter))

app = Flask(__name__)
instrument_app(app)

@app.route("/")
def hello():
    @copy_current_request_context
    def nest():
        return "Hello!"

    return nest()

if __name__ == "__main__":
    app.run(debug=True)

What is the expected behavior?

Span(name="hello", context=SpanContext(trace_id=0x5f518f71873e44725041844a36ccc493, span_id=0xf198dc7dbbf56851, trace_state={}), kind=SpanKind.SERVER, parent=None, start_time=2019-12-30T10:35:25.124501Z, end_time=2019-12-30T10:35:25.125568Z)
127.0.0.1 - - [30/Dec/2019 11:35:25] "GET / HTTP/1.1" 200 -

What is the actual behavior?

Span(name="hello", context=SpanContext(trace_id=0x5f518f71873e44725041844a36ccc493, span_id=0xf198dc7dbbf56851, trace_state={}), kind=SpanKind.SERVER, parent=None, start_time=2019-12-30T10:35:25.124501Z, end_time=2019-12-30T10:35:25.125568Z)
Setting attribute on ended span.
Setting attribute on ended span.
Calling set_status() on an ended span.
127.0.0.1 - - [30/Dec/2019 11:35:25] "GET / HTTP/1.1" 200 -

Additional context

The example to reproduce doesn't make much sense, as to why use the copy request decorator, but in a real application, it is needed when working in a multithreaded environment.

I notice there is a lot of functional overlap with the wsgi version, wouldn't it be feasible to rely more on the wsgi implementation, and simply add the extra flask specific information on top of that?

Note, that the wsgi implementation does not suffer from this issue.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions