open-telemetry / open-telemetry/opentelemetry-python-contrib

Span names for flask requests only show the HTTP method if they didn't match a route

Open
#2,155 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
1.1k
Forks
1.1k
Avg merge
4d 15h
Merged PRs (30d)
16

Description

Steps to reproduce

  1. Instrument a Flask app with FlaskInstrumentor
  2. Visit a URL that matches a route and returns 200
  3. Visit a different URL that doesn't match a route and returns 404
  4. Check the span names for the two requests

Example code:

from flask import Flask
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor

tracer_provider = TracerProvider()
processor = SimpleSpanProcessor(ConsoleSpanExporter(formatter=lambda span: f'!!! Span: {span.name}\n'))
tracer_provider.add_span_processor(processor)

app = Flask(__name__)
FlaskInstrumentor().instrument_app(app, tracer_provider=tracer_provider)


@app.route('/item/<int:item_id>')
def get_item(item_id):
    return f'item {item_id}'


app.run()

Then open in your browser:

Note that the second request has the right general pattern but fails to match a route purely because foobar can't be converted to an integer.

What is the expected behavior?

!!! Span: GET /item/<int:item_id>
!!! Span: GET /item/foobar

What is the actual behavior?

The first GET is missing:

!!! Span: /item/<int:item_id>
!!! Span: GET /item/foobar

Additional context

The reason for this is clearly visible in the code. Requests with a matching Flask route don't have the HTTP method included:

https://github.com/open-telemetry/opentelemetry-python-contrib/blob/47caeab7aff47070c565cd90536a39ec5eb06f34/instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/__init__.py#L295-L300

But if they don't match, they fallback to the WSGI span name which includes the method:

https://github.com/open-telemetry/opentelemetry-python-contrib/blob/47caeab7aff47070c565cd90536a39ec5eb06f34/instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py#L451-L466

BTW, this PR comment requested removing name_callback which would have allowed customising the span name myself to work around this issue, but I don't see the reasoning behind this.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in instrumentation/opentelemetry-instrumentation-flask/src/opentelemetry/instrumentation/flask/init.py at the linked span-name logic, then compare it with instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/init.py. Verify the matched-route and unmatched-route examples produce consistent HTTP-method-prefixed span names.

Written by the indexing model from the issue text.

Assessment

Tech stack
flask, python
Domain
backend, observability
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.