Performance Monitoring doesn't work with Werkzeug DebuggedApplication
How do you use Sentry?
Sentry Saas (sentry.io)
Version
1.5.10
Steps to Reproduce
- Use Flask Integration
- Enable Werkzeug's
DebugApplicationmode - Set the
SENTRY_DSNenvironment variable - Run web server
- Execute a GET request to any endpoint
Minimal example code:
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from werkzeug.debug import DebuggedApplication
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
SENTRY_ENVIRONMENT = os.getenv("SENTRY_ENVIRONMENT", "dev")
SENTRY_SAMPLE_RATE = float(os.getenv("SENTRY_SAMPLE_RATE", "0.8"))
SENTRY_TRACE_SAMPLE_RATE = float(os.getenv("SENTRY_TRACE_SAMPLE_RATE", "0.8"))
integrations = [FlaskIntegration(transaction_style="url"), SqlalchemyIntegration()]
sentry_sdk.init(
integrations=integrations,
sample_rate=SENTRY_SAMPLE_RATE,
traces_sample_rate=SENTRY_TRACE_SAMPLE_RATE,
environment=SENTRY_ENVIRONMENT,
send_default_pii=True,
)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///:memory:"
app.wsgi_app = DebuggedApplication(app.wsgi_app, True)
db = SQLAlchemy(app)
@app.route('/db')
def entry_point():
db.engine.execute("SELECT name FROM sqlite_master")
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
Expected Result
Sentry should correctly fetch the transaction name from the endpoint as well as capture spans that occurred during the request execution.
We expect the following in the performance tab. These screenshots are from running the same code but with the DebuggedApplication line commented out:
Transaction View
Event Details

Actual Result
Sentry has the name of generic WSGI request for all transactions in the performance tab of the dashboard. They're only differentiated by their HTTP Method. They also do not correctly include the Spans that make up a transaction.
Through debugging, I figured out that somehow the order of the steps is different. Having DebuggedApplication active results in a Transaction.finish() method being called before the transaction has had its name set here
Screenshots of actual result:
Performance:
Transaction
Event Details:

This is obviously not a big issue, however, as I did spent 3 days debugging it I wanted to document this behaviour in case someone else is also struggling with it.
Hey @BoyanYK
Thanks for reporting this. This can definitely be improved!
I also think it (hopefully) is not a big change to have proper data when DebuggedApplication is enabled.
Could you submit a PR that fixes this? We are always happy to help merge the PR to improve integrations!
@BoyanYK After investigating this issue, we would recommend that you fix the issue by simply removing the app.wsgi_app = DebuggedApplication(app.wsgi_app, True) line from your code.
During our investigation, we discovered that the DebuggedApplication line is redundant because when passing debug=True to Flask's app.run function, Flask already automatically wraps the application in Werkzeug's DebuggedApplication internally. Using both the DebuggedApplication and the debug=True option causes the app to be double-wrapped in the debugger (you can observe this when starting the Flask app, since two different debugger PINs are outputted). As you already noted under the "Expected Results" of the issue, removing the DebuggedApplication line fixes the issue with the transaction names that you observed, so we would recommend removing the line to fix the problem.
We are closing this issue for now because this double-wrapping of the Flask application in the DebuggedApplication is not a supported use case, and in this case, the problem can be easily fixed by removing the DebuggedApplication line and simply using Flask's debug=True option.
However, if anyone observes a similar issue with some other Flask middleware, please feel free to submit a new issue which references this one.
Thanks for taking the time to follow up on this! This is an interesting finding I definitely wasn't aware of - that the application would be wrapped in a debugger twice - it does confirm that it isn't a bug.