Python
Traces | Metrics | App Logs | Custom Logs | Profiling |
---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ✅ |
This guide walks you through setting up Application Performance Monitoring (APM) on a Python application. These instructions can also be found on the Installation page in your Middleware Account. View example code here.
Prerequisites
- Python Version 3.8+: Verify with
python3 --version
- Pip Version 23.1.2+: Verify with
pip --version
Installation
1 Setup Virtual Environment
python -m venv myenv source myenv/bin/activate
2 Install Middleware Python APM Package
To install Middleware Python APM Package run the command in your terminal:
pip install middleware-io
3 Install OpenTelemetry automatic instrumentation libraries:
Run the command to install instrumentation library:
middleware-bootstrap -a install
The middleware-bootstrap -a install
command reads through the list of packages installed in your active site-packages
folder, and installs the corresponding instrumentation libraries for these packages, if applicable. For example, if you already installed the flask
package, running middleware-bootstrap -a install
will install opentelemetry-instrumentation-flask
for you. The Middleware Python agent will use monkey patching to modify functions in these libraries at runtime.
Ensure library is installed properly with command:
pip list | grep -i flask Flask 3.0.3 opentelemetry-instrumentation-flask 0.48b0
For Containerized Application add command in dockerfile:
RUN middleware-bootstrap -a install
Instrumentation
To begin with instrumentation, you will need to obtain your API key from Middleware App. Additionally, ensure that the Middleware agent is installed and properly configured as per your application Host Platform and Operating System.
Based on your application requirements, you can choose one of the following methods for instrumentation:
Zero Code Instrumentation: This method allows you to instrument your application without modifying any code. It is ideal for quick setups and minimal code. It requires to set environments only.
Tracker Function Based Instrumentation: If you require more control over the instrumentation process, this method involves using a tracker function to integrate APM directly into your application’s code.
Method 1: Python Zero-Code Instrumentation
Zero code instrumentation allows you to monitor your Python application without modifying the application code. This can be achieved by setting environment variables that configure the application with Middleware Application Performance Monitoring (APM) tool.
Example:
You can set the following environment variables in your shell to auto instrument:
export MW_API_KEY='<MW_API_KEY>' export MW_TARGET='https://<MW_UID>.middleware.io:443' export MW_SERVICE_NAME='MyFlaskServer' middleware-run python app.py
For Advanced Configuration explore all configuration options with environments for the Middleware APM.
Automatic instrumentation with Python uses a Python agent that can be attached to any Python application. This agent primarily uses monkey patching to modify library functions at runtime, allowing for the capture of telemetry data from many popular libraries and frameworks.
Method 2: Python Tracker Function Based Instrumentation
If you prefer more control and want to integrate APM directly into your application, you can use a middleware function like mw_tracker
. This method requires adding a specific function call in your application's code .
Example: Using mw_tracker
Function from Middleware
main.py
from flask import Flask # Import the mw_tracker from middleware to your app from middleware import mw_tracker, MWOptions, record_exception, DETECT_AWS_EC2 mw_tracker( MWOptions( access_token="<MW_API_KEY>", target="https://<MW_UID>.middleware.io:443", console_exporter=True, debug_log_file=True,
Run Your Application
To run your application, use the following command:
MW_TRACKER=True middleware-run python app.py
The MW_TRACKER=True
is required if mw_tracker() function is used for instrumentation.
Configuration
Advanced Configuration
Use Attributes and Environment Variables to configure Middleware APM.
This table shows the available configuration settings along with the corresponding environment variables that can be used instead.
Config Attribute | Environment Variable | Description | Example |
---|---|---|---|
access_token | MW_API_KEY | Token required for authentication. | access_token = "whkvkobudfitutobptgonaezuxpjjypnejbb" |
service_name | MW_SERVICE_NAME or OTEL_SERVICE_NAME | The name of your application and it will appear in the UI to filter your data. | service_name = "MyPythonServer" |
collect_traces | MW_APM_COLLECT_TRACES | Flag to enable or disable trace collection. Defaults to True. | collect_traces = True |
collect_metrics | MW_APM_COLLECT_METRICS | Flag to enable or disable metrics collection. Defaults to True. | collect_metrics = False |
collect_logs | MW_APM_COLLECT_LOGS | Flag to enable or disable log collection. Defaults to True. | collect_logs = True |
collect_profiling | MW_APM_COLLECT_PROFILING | Flag to enable or disable profiling collection. Defaults to False. | collect_profiling = True |
log_level | MW_LOG_LEVEL or OTEL_LOG_LEVEL | Sets the logging level (INFO, DEBUG, WARNING, ERROR). Defaults to INFO | log_level = "DEBUG" |
mw_agent_service | MW_AGENT_SERVICE | Address of the middleware agent service. Defaults to localhost. | Set mw_agent_service="172.17.0.1" for Docker or mw_agent_service="mw-service.mw-agent-ns.svc.cluster.local" for Kubernetes Application. |
target | MW_TARGET or OTEL_EXPORTER_OTLP_ENDPOINT | Target endpoint for the OTLP exporter. Defaults to http://localhost:9319. | target = "https://myapp.middleware.io:443" |
custom_resource_attributes | MW_CUSTOM_RESOURCE_ATTRIBUTES | Custom resource attributes for enhanced telemetry context. | custom_resource_attributes="call_id=12345678, request_id=987654321" |
otel_propagators | MW_PROPAGATORS or OTEL_PROPAGATORS | Propagators for context propagation. Defaults to b3. | otel_propagators = "b3,tracecontext" |
console_exporter | MW_CONSOLE_EXPORTER | Flag to enable console exporter. Dumps telemetry data to console. Defaults to False. | console_exporter = True |
debug_log_file | MW_DEBUG_LOG_FILE | Flag to enable debug logging to file. Only used if console_exporter is enabled. Defaults to False. | debug_log_file = True |
project_name | MW_PROJECT_NAME | Name of the project for identification. | project_name = "TestingProject" |
sample_rate | MW_SAMPLE_RATE | Sample rate for telemetry data from (0 to 1). AlwaysOn (1), AlwaysOff (0), or a TraceIdRatio as 1/N. Defaults to 1. | sample_rate = 0.5 |
detectors | MW_DETECTORS | Detectors for AWS, Azure, GCP, or environment variables. | detectors = [DETECT_AWS_LAMBDA, DETECT_GCP] MW_DETECTORS = "aws_lambda,gcp" |
All OpenTelemetry environment variables are supported and take the highest priority.
Host Based Configuration
If you are deploying the host using Kubernetes or Docker you will need to set the mw_agent_service
to the location of the mw-agent.
This variable can be ignored when the agent is running on the same host as the application.
Add the mw_agent_service
or export environment variable to your application:
docker run \ -e MW_AGENT_SERVICE=<DOCKER_BRIDGE_GATEWAY_ADDRESS> \ -p 8000:8000 -it --rm --name CONTAINER_NAME DOCKER_IMAGE:IMAGE_TAG
The DOCKER_BRIDGE_GATEWAY_ADDRESS
is the IP address of the gateway between the Docker host and bridge network. This is 172.17.0.1
by default. Learn more about Docker bridge networking here
Add the following command to your Dockerfile
after the pip install
command:
RUN middleware-bootstrap -a install
Identify the namespace where the Infra Agent is running:
kubectl get service --all-namespaces | grep mw-service
Then add the following environment variable to your application deployment YAML file:
MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local
Serverless Configuration
If you are running your Python application in a serverless setup without the mw-agent, the MW_API_KEY
and MW_TARGET
variables are required when running the application:
export MW_API_KEY='<MW_API_KEY>' export MW_TARGET='https://<MW_UID>.middleware.io:443' middleware-run python app.py
Framework Specific Configurations
Specific frameworks require different configurations when being run, which can be found below:
export DJANGO_SETTINGS_MODULE='mysite.settings' middleware-run python manage.py runserver
export MW_API_KEY='<MW_API_KEY>' export MW_TARGET='https://<MW_UID>.middleware.io:443' export DJANGO_SETTINGS_MODULE='demo.settings' middleware-run gunicorn -c conf/gunicorn.conf.py --workers=4 --bind 0.0.0.0:8000 --timeout 120 demo.wsgi
export MW_API_KEY='<MW_API_KEY>' export MW_TARGET='https://<MW_UID>.middleware.io:443' middleware-run uvicorn main:app --host localhost --port 5002
Explore more OpenTelemetry supported libraries here.
Sending Custom Data
Custom Metrics
Create and use a meter to send custom metrics:
main.py
from opentelemetry.metrics import get_meter_provider # Create a meter meter = get_meter_provider().get_meter("custom_meter") # Create a counter request_counter = meter.create_counter( "request_counter", description="Counts the number of requests" )
Custom Traces
Create and use a tracer to send custom spans:
main.py
from opentelemetry.trace import get_tracer # Create a tracer tracer = get_tracer("custom_tracer") # Start a span with tracer.start_as_current_span("custom_span"): print("Doing some work within the span")
Custom Logs
Utilize logging
method to send logs with a given priority. It is recommended to integrate these calls function inside your existing logger:
main.py
logging.info("info sample") logging.warning("Sample Warning Log") logging.error("Sample Error Log.", extra={'tester': 'Alex'})
Custom Attributes
All custom attributes collected will be available as filtering and grouping functions inside of the Middleware platform.
Using similar methods from the above Traces and Logs sections you can attach custom attributes to any trace, span or log:
main.py
from opentelemetry.trace import get_tracer tracer = get_tracer("custom_tracer") with tracer.start_as_current_span("span_with_attributes") as span: span.set_attribute("user.email", "[email protected]") span.set_attribute("user.id", 1234)
Adding Stack Traces
Use record_exception()
method to record a stack trace when an exception occurs:
main.py
from middleware import record_exception try: print("Divide by zero:",1/0) except Exception as e: record_exception(e)
Continuous Profiling
By default the Python APM captures Continuous Profiling data which provides real-time performance insights from your application to enable rapid identification of resource allocation, bottlenecks, and more. Navigate to the Continuous Profiling section to learn more about using Continuous Profiling with Middleware.
To enable continous profiling for your python application. Install required profiling dependencies with below command:
pip install middleware-io[profiling]
Enable profiling with collect_profiling
or export MW_APM_COLLECT_PROFILING=True
Example application
Below is a sample python flask server application.
main.py
import logging from middleware import mw_tracker, MWOptions, record_exception, DETECT_AWS_EC2 mw_tracker( MWOptions( access_token="<MW_API_KEY>", target="https://<MW_UID>.middleware.io:443", console_exporter=True, debug_log_file=True, service_name="MyPythonServer", otel_propagators = "b3,tracecontext",
Start the server
MW_SERVICE_NAME="flask-server" middleware-run python app.py
Troubleshooting and Debugging
To help troubleshoot and debug issues with your application's telemetry, you can enable specific settings in the mw_tracker
function or use environment variables. These settings allow you to export telemetry data to the console, save them to log files, or debug basic information logs.
Toggling Basic Information Logs
Toggle info logs on or off to focus on debugging specific issues:
#in the `mw_tracker` function from middleware log_level = "DEBUG" #as an env variable MW_LOG_LEVEL = "DEBUG"
Exporting Telemetry Data to the Console
When debugging in a dev environment it may be useful to view the telemetry data directly in the console. Setting the console_exporter
to true
will print telemetry data like traces, metrics, and logs in your terminal or console.
#in the `mw_tracker` function from middleware console_exporter = true #as an env variable MW_CONSOLE_EXPORTER = true
Saving Telemetry Data to Log Files
You may save telemetry data to log files by enabling the debug_log_file
setting. The logs will be written to respective files such as mw-traces.log, mw-metrics.log, and mw-logs.log.
#in the `mw_tracker` function from middleware debug_log_file = true #as an env variable MW_DEBUG_LOG_FILE = true
Python package installation failure
The Python package installs require gcc
and gcc-c++
, which you may need to install if you’re running a slim version of Linux, such as CentOS.
yum -y install python3-devel yum -y install gcc-c++
apt install -y python3-dev apt install -y build-essential
apk add python3-dev apk add build-base
Missing Parent Span
Try tunning batch export interval using OTel Environment variable
OTEL_BSP_SCHEDULE_DELAY = 100
For more info on Batch Span Processor here
Need assistance or want to learn more about Middleware? Contact our support team in Slack.