Python
Traces | Metrics | App Logs | Custom Logs | Profiling |
---|---|---|---|---|
✅ | ✅ | ✅ | ✅ | ✅ |
1. Prerequisites
Before you instrument anything, make sure the basics are in place:
- Python 3.8+ and pip 23.1.2+ – verify your versions:
1python3 --version 2pip --version
- (Host mode only) If your app runs in a container, point it at the Host Agent using
MW_AGENT_SERVICE
.- Docker default bridge gateway:
172.17.0.1
- Kubernetes service name:
mw-service.mw-agent-ns.svc.cluster.local
(discover withkubectl get service --all-namespaces | grep mw-service
).
- Docker default bridge gateway:
2. Install
Create an isolated environment, install the SDK, then add auto-instrumentation shims for your frameworks:
1python -m venv .venv
2source .venv/bin/activate
3
4# SDK
5pip install middleware-io
6
7# (optional) enable continuous profiling features
8pip install 'middleware-io[profiling]'
9
10# Add OpenTelemetry auto-instrumentation libraries for installed packages (e.g., Flask)
11middleware-bootstrap -a install
What middleware-bootstrap -a install
does: it scans your active site-packages
and installs the matching opentelemetry-instrumentation-*
libraries for any frameworks you already have (e.g., Flask → opentelemetry-instrumentation-flask
).
You can confirm with pip list | grep -i flask
. For containers, add RUN middleware-bootstrap -a install
to your Dockerfile.
3. Instrumentation
Pick Host (with the Middleware Host Agent) or Serverless (send directly to Middleware). Within each, choose Auto (zero-code) or Manual (call the tracker in code).
Auto instrumentation (zero-code) Use the CLI wrapper that the SDK installs; it starts your app with the correct instrumentation:
1export MW_SERVICE_NAME='MyPythonApp' 2middleware-run python app.py
The SDK adds a
middleware-run
CLI to your venv; use it instead of raw commands like flask run so telemetry is captured. In Host mode, the OTLP target defaults to the local agent (http://localhost:9319
).Manual instrumentation (in code) Call
mw_tracker(...)
once at startup for more control (sampling, detectors, debug output, etc.):1from middleware import mw_tracker, MWOptions 2 3mw_tracker(MWOptions( 4 service_name="MyPythonApp", 5 console_exporter=True, # echo telemetry to stdout (dev only) 6 log_level="DEBUG", 7))
Run it with:
1export MW_TRACKER=True 2middleware-run python app.py
MW_TRACKER=True
is required when you instrument usingmw_tracker()
.
Auto instrumentation (zero-code) Set the tenant endpoint and API key, then start with the same runner:
1export MW_API_KEY='<MW_API_KEY>' 2export MW_TARGET='https://<MW_UID>.middleware.io:443' 3export MW_SERVICE_NAME='MyPythonApp' 4middleware-run python app.py
In serverless mode the app exports directly to Middleware, so both
MW_API_KEY
andMW_TARGET
are required. (docs.middleware.io)Manual instrumentation (in code) Supply the target and token via
MWOptions
:1from middleware import mw_tracker, MWOptions, DETECT_AWS_EC2 2 3mw_tracker(MWOptions( 4 access_token="<MW_API_KEY>", 5 target="https://<MW_UID>.middleware.io:443", 6 service_name="MyPythonApp", 7 detectors=[DETECT_AWS_EC2], # example 8 otel_propagators="b3,tracecontext", 9 console_exporter=True, 10 log_level="DEBUG", 11))
Run it with:
1export MW_TRACKER=True 2middleware-run python app.py
4. Advanced configuration (optional)
- Service name (two ways):Or set
1export MW_SERVICE_NAME='MyPythonApp'
service_name
inMWOptions(...)
. - Continuous profiling:
1pip install 'middleware-io[profiling]' 2 export MW_APM_COLLECT_PROFILING=True 3 # serverless requires MW_API_KEY + MW_TARGET as above
Framework-specific run examples:
Django
1export DJANGO_SETTINGS_MODULE='mysite.settings' 2middleware-run python manage.py runserver
Gunicorn
1export MW_API_KEY='<MW_API_KEY>' 2export MW_TARGET='https://<MW_UID>.middleware.io:443' 3export DJANGO_SETTINGS_MODULE='demo.settings' 4middleware-run gunicorn -c conf/gunicorn.conf.py --workers=4 --bind 0.0.0.0:8000 --timeout 120 demo.wsgi
Uvicorn (FastAPI/Starlette)
1export MW_API_KEY='<MW_API_KEY>' 2export MW_TARGET='https://<MW_UID>.middleware.io:443' 3middleware-run uvicorn main:app --host localhost --port 5002
Use the serverless env set if you’re not running a Host Agent.)
Host networking in containers:
- Docker default gateway is
172.17.0.1
. - On Kubernetes, find the service and set
MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local
.
- Docker default gateway is
What “Zero-code” actually does: automatic patching via monkey-patching of popular libraries at runtime (e.g., Flask), driven by the instrumentation packages you installed with middleware-bootstrap
.
5. Sending custom data
Custom Metrics
Create and use a meter to send custom metrics:
1from opentelemetry.metrics import get_meter_provider 2 3# Create a meter 4meter = get_meter_provider().get_meter("custom_meter") 5 6# Create a counter 7request_counter = meter.create_counter( 8 "request_counter", description="Counts the number of requests" 9) 10 11# Use the counter 12request_counter.add(1, {"endpoint": "/home"})
Custom Traces
Create and use a tracer to send custom spans:
1from opentelemetry.trace import get_tracer 2 3# Create a tracer 4tracer = get_tracer("custom_tracer") 5 6# Start a span 7with tracer.start_as_current_span("custom_span"): 8 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:1logging.info("info sample") 2logging.warning("Sample Warning Log") 3logging.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:
1from opentelemetry.trace import get_tracer 2 3tracer = get_tracer("custom_tracer") 4 5with tracer.start_as_current_span("span_with_attributes") as span: 6 span.set_attribute("user.email", "[email protected]") 7 span.set_attribute("user.id", 1234)
Adding Stack Traces
Use
record_exception()
method to record a stack trace when an exception occurs:1from middleware import record_exception 2 try: 3 print("Divide by zero:",1/0) 4 except Exception as e: 5 record_exception(e)
6. Environment variables
OTel env vars are supported and take the highest priority if present. Then Middleware env vars, then code options.
Config attribute | Environment variable(s) | Description/default | Example |
---|---|---|---|
access_token | MW_API_KEY | Auth token (required for serverless/direct). | xxxxxxxx… |
service_name | MW_SERVICE_NAME, OTEL_SERVICE_NAME | Service name shown in APM. | payments-api |
collect_traces | MW_APM_COLLECT_TRACES | Enable traces (default true). | true |
collect_metrics | MW_APM_COLLECT_METRICS | Enable metrics (default true). | true |
collect_logs | MW_APM_COLLECT_LOGS | Enable logs (default true). | true |
collect_profiling | MW_APM_COLLECT_PROFILING | Enable profiling (requires profiling extra). | true |
log_level | MW_LOG_LEVEL, OTEL_LOG_LEVEL | Logging level (default INFO). | DEBUG |
mw_agent_service | MW_AGENT_SERVICE | Host Agent address in containers. | 172.17.0.1 / mw-service.mw-agent-ns... |
target | MW_TARGET, OTEL_EXPORTER_OTLP_ENDPOINT | OTLP endpoint (Host default: http://localhost:9319). | https://<MW_UID>.middleware.io:443 |
custom_resource_attributes | MW_CUSTOM_RESOURCE_ATTRIBUTES | Comma-sep k=v list. | call_id=123,region=us-east-1 |
otel_propagators | MW_PROPAGATORS, OTEL_PROPAGATORS | Context propagation (default b3). | b3,tracecontext |
console_exporter | MW_CONSOLE_EXPORTER | Echo telemetry to console (dev). | true |
debug_log_file | MW_DEBUG_LOG_FILE | Log telemetry to files (with console exporter). | true |
project_name | MW_PROJECT_NAME | Logical app/project name. | ShopApp |
sample_rate | MW_SAMPLE_RATE | 0..1 (AlwaysOn=1, AlwaysOff=0). | 0.5 |
detectors | MW_DETECTORS | e.g., aws_lambda,gcp,azure,envvars . | aws_lambda,gcp |
7. View your data
After you start the app, give it 3–5 minutes, then open APM → Traces, Logs, and APM → Continuous Profiling in Middleware. See “Application Instrumentation” for where to find dashboards, trace viewer, Log Explorer, and Alerts.
8. Troubleshooting
- No data (Host mode): Ensure you’re using
middleware-run
, the Host Agent is installed, and (in containers)MW_AGENT_SERVICE
is set to the correct address/service. - No data (Serverless): Make sure both
MW_API_KEY
andMW_TARGET
are exported before starting. - Instrumentation didn’t hook: Re-run
middleware-bootstrap -a install
after adding frameworks, and verify withpip list
thatopentelemetry-instrumentation-*
packages exist. - Need to confirm
register
/init ran? Temporarily setMW_CONSOLE_EXPORTER=true
(andMW_DEBUG_LOG_FILE=true
) to echo spans/logs to stdout/files while you test. - Kubernetes reachability: find the service, then set
MW_AGENT_SERVICE=mw-service.mw-agent-ns.svc.cluster.local
.
Need assistance or want to learn more about Middleware? Contact our support team at [email protected] or join our Slack channel.