The WSGI and ASGI standards provide a common layer for the development of web frameworks and servers in Python. Most popular Python web frameworks follow these standards, allowing for any Python web application to be deployed with any Python web server.
AppSignal supports instrumentation for generic WSGI and ASGI web applications through OpenTelemetry.
Install the Instrumentation
First, install either the
opentelemetry-instrumentation-wsgi or the
opentelemetry-instrumentation-asgi package, depending the gateway interface used in the application. To add it to your project, add the following line to your
# requirements.txt # For a WSGI application: opentelemetry-instrumentation-wsgi # For an ASGI application: opentelemetry-instrumentation-asgi
In your application's entry point (usually named
app.py), before your application is initialised, call
appsignal.start() to start your application:
from __appsignal__ import appsignal appsignal.start() # ... the rest of your code goes here ...
OpenTelemetryMiddleware from the corresponding OpenTelemetry instrumentation, and wrap your application with it:
# For a WSGI application: from opentelemetry.instrumentation.wsgi import OpenTelemetryMiddleware # For an ASGI application: from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware my_app = # ... your WSGI/ASGI application goes here ... my_app = OpenTelemetryMiddleware(my_app)
By default, a generic WSGI or ASGI instrumentation will not have the necessary context to understand how routing is structured in your application. As such, the performance samples that AppSignal receives will not be grouped correctly. You must add routing information to the OpenTelemetry span manually.
One way to do so is by following OpenTelemetry's HTTP semantic conventions, setting the
http.route attribute in your route handlers:
from opentelemetry.trace import get_current_span def get_user_route_handler(): get_current_span().set_attribute("http.route", "/users/:user_id") # ... your route handler goes here ...
AppSignal will automatically use the value of this attribute and use it to group requests, along with the request method. For example, a GET request that is handled by this method will appear as
GET /users/:user_id in the AppSignal performance samples panel.
If you prefer to group requests in some other way (for example, by referring to the method or class that implements them) you can use the
from opentelemetry.trace import get_current_span class UserHandlers: def show(): get_current_span().set_attribute("appsignal.root_name", "UserHandlers#show") # ... your route handler goes here ...
appsignal.root_name, the request method will not be used. The value provided (in this case,
UserHandlers#show) will be used to group all requests handled by this method.