Azure App Service instrumentation for Python
Supported for App Service hosting plans on Linux only.
Use the APM Python Library to instrument your Azure App Service to gain insights into the application process at code-level. SolarWinds Observability supports the App Service runtime with library version 7.1.0 or later.
Install
For the typical App Service deployment scenario where build automation is enabled (SCM_DO_BUILD_DURING_DEPLOYMENT=true), add solarwinds_apm as a dependency for your application. Example using requirements.txt:
Flask==3.1.0 gunicorn solarwinds_apm
Then add an app setting POST_BUILD_COMMAND to run the OpenTelemetry bootstrap install as a post-build step. In the Azure portal this is under Settings > Environment variables > App settings:
| Name | Value |
|---|---|
| POST_BUILD_COMMAND | opentelemetry-bootstrap --action=install |
Please reference the official Microsoft documentation on how to customize build automation for more details.
For a deployment scenario where build automation is disabled, e.g. deploy via custom container image, your application must include both solarwinds_apm and all the dependencies that OpenTelemetry bootstrap would install. In essence it requires performing the steps described in Install the Python Library as part of the container or deployable artifact build.
Configure
Environment variables supported by APM Python can be set as app settings, in the Azure portal this is under Settings > Environment variables > App settings. These are the required settings:
| Name | Value |
|---|---|
| SW_APM_SERVICE_KEY | The service name portion, that is, the string after :, is ignored and the App Service app name (WEBSITE_SITE_NAME) is used as the SolarWinds Observability service name. To override with an explicit service name, set the OTEL_SERVICE_NAME variable. |
| SW_APM_COLLECTOR |
Determine based on your data center, for example:
|
Enable
The standard way to enable the Python Library cannot be used for a typical App Service since by default it runs gunicorn which is a pre-fork webserver that causes issues with the way OTel Python, and a custom distribution of it such as APM Python, initializes auto-instrumentation. Please see the description in https://opentelemetry.io/docs/zero-code/python/troubleshooting/#pre-fork-server-issues and use one of the workarounds listed in that page according to your specific scenario. Below are a few examples of the programmatic auto-instrumentation approach that have been tested with APM Python:
In the application code
Update your application’s entry point script with OTel initialization, which will be run on startup in each forked worker process. This is a simple Flask example:
# Initialize OpenTelemetry inside the worker process after server fork. try: from opentelemetry.instrumentation.auto_instrumentation import initialize initialize() except ImportError: pass app = Flask(__name__)
In a customized startup command
Gunicorn’s configuration file can be used to define a post_fork initialization of auto-instrumentation in each worker process. The App Service startup command can be customized to use a specific configuration file, in the Azure portal this can be set under Settings > Configuration > Stack settings. An example of this approach where the Flask app is app:app:
Custom startup command
gunicorn --config gunicorn_config.py --bind 0.0.0.0 --timeout 600 --access-logfile '-' --error-logfile '-' app:app
gunicorn_config.py content
from opentelemetry.instrumentation.auto_instrumentation import initialize
def post_fork(server, worker):
initialize()