Flask instrumentation for Watchlog APM with JSON OTLP export
Project description
flask_watchlog_apm
🔗 Website: https://watchlog.io
flask_watchlog_apm is a lightweight APM integration for Flask, built on OpenTelemetry. It provides:
- Auto-instrumentation for Flask routes and underlying HTTP calls
- Manual custom spans via the OpenTelemetry API
- JSON-over-HTTP exporter (OTLP) compatible with Watchlog Agent
- Environment detection (local vs in-cluster Kubernetes)
- Configurable sampling, error-only and slow-only span export
Installation
Install from PyPI:
pip install flask_watchlog_apm
Or directly from GitHub:
pip install git+https://github.com/Watchlog-monitoring/flask_watchlog_apm.git
Quick Start
Initialize the APM before registering any routes:
# main.py
from flask import Flask
from flask_watchlog_apm.instrument import instrument_app
app = Flask(__name__)
# 1) Initialize Watchlog APM
instrument_app(
app,
service_name="my-flask-service", # your service name
headers={"Authorization": "Bearer <token>"},
sample_rate=0.5, # random sample rate (0.0–1.0, capped at 0.3)
send_error_spans=True, # always export error spans
error_tps=10, # max 10 error spans per second
slow_threshold_ms=100 # always export spans >100ms
)
# 2) Define your routes
@app.route("/")
def hello():
return "Hello, Watchlog APM!"
# 3) Run your app
if __name__ == "__main__":
app.run(host="0.0.0.0", port=6000, debug=True)
What happens?
- Flask endpoints and outbound HTTP calls (via
requests) are auto-instrumented. - Spans are batched and sent as JSON to your Watchlog Agent (local or in-cluster).
- Configurable filters—sampling, error-only, slow-only—are applied.
Configuration Options
| Parameter | Type | Default | Description |
|---|---|---|---|
service_name |
str |
required | Name of your Flask service |
otlp_endpoint |
str |
http://localhost:3774/apm |
Base OTLP URL (overrides auto-detection if different from default) |
headers |
dict |
{} |
Additional HTTP headers for OTLP requests |
batch_max_size |
int |
200 |
Maximum spans per batch |
batch_delay_ms |
int |
5000 |
Delay in milliseconds between batch exports |
sample_rate |
float |
1.0 |
Random sampling rate (0.0–1.0, internal cap at 0.3) |
send_error_spans |
bool |
False |
If True, always export spans with non-OK status |
error_tps |
int |
None |
Max error spans to export per second (None = unlimited) |
slow_threshold_ms |
int |
0 |
If >0, always export spans slower than this threshold (ms) |
export_timeout |
float |
10.0 |
HTTP request timeout (seconds) for exporter POSTs |
Manual Custom Spans
Use the OpenTelemetry API to create custom spans:
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
@app.route("/db")
def fetch_db():
with tracer.start_as_current_span("db.query", attributes={"db.system":"postgresql"}):
# your DB logic here
return "db query done"
Environment Detection
The package automatically detects the runtime environment:
- Local (non-K8s): sends to
http://localhost:3774/apm - Kubernetes (in-cluster): sends to
http://watchlog-python-agent.monitoring.svc.cluster.local:3774/apm
Detection checks in order:
- Existence of
/var/run/secrets/kubernetes.io/serviceaccount/token - Presence of
kubepodsin/proc/1/cgroup - DNS lookup of
kubernetes.default.svc.cluster.local
Manual Override: You can override the endpoint by passing otlp_endpoint option in instrument_app() function
Docker Setup
When running your Flask app in Docker, you need to configure the correct agent endpoint.
Using otlp_endpoint Option (Recommended for Docker)
# main.py
from flask import Flask
from flask_watchlog_apm.instrument import instrument_app
app = Flask(__name__)
# Initialize Watchlog APM with explicit agent URL for Docker
instrument_app(
app,
service_name="my-flask-service",
otlp_endpoint="http://watchlog-agent:3774/apm", # Use container name
sample_rate=0.5,
send_error_spans=True,
error_tps=10,
slow_threshold_ms=100
)
@app.route("/")
def hello():
return "Hello, Watchlog APM!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=6000, debug=True)
Docker Compose Example:
version: '3.8'
services:
watchlog-agent:
image: watchlog/agent:latest
container_name: watchlog-agent
ports:
- "3774:3774"
environment:
- WATCHLOG_APIKEY=your-api-key
- WATCHLOG_SERVER=https://log.watchlog.ir
networks:
- app-network
flask-app:
build: .
container_name: flask-app
ports:
- "6000:6000"
environment:
- FLASK_ENV=production
depends_on:
- watchlog-agent
networks:
- app-network
networks:
app-network:
driver: bridge
Docker Run Example:
# 1. Create network
docker network create app-network
# 2. Run Watchlog Agent
docker run -d \
--name watchlog-agent \
--network app-network \
-p 3774:3774 \
-e WATCHLOG_APIKEY="your-api-key" \
-e WATCHLOG_SERVER="https://log.watchlog.ir" \
watchlog/agent:latest
# 3. Run Flask app (make sure your code sets otlp_endpoint='http://watchlog-agent:3774/apm')
docker run -d \
--name flask-app \
--network app-network \
-p 6000:6000 \
my-flask-app
Important Notes:
- When using Docker, use the container name as the hostname (e.g.,
watchlog-agent) - Both containers must be on the same Docker network
- The agent must be running before your app starts
- Set the
otlp_endpointoption in your code to point to the agent container - If
otlp_endpointis not provided (or set to default), auto-detection will be used
License
MIT © Mohammadreza
Built for Watchlog.io
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file flask_watchlog_apm-1.1.0.tar.gz.
File metadata
- Download URL: flask_watchlog_apm-1.1.0.tar.gz
- Upload date:
- Size: 6.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
259808067e7101338f723ef40e21098d5054f43def3839859c0821fd16ead6a0
|
|
| MD5 |
75e76c9d54decb42a116bc018942e090
|
|
| BLAKE2b-256 |
602e3d8f264e667af9c50bccaf8905c5d2777ffb19773ab89332c0d51532dfad
|