FastAPI instrumentation for Watchlog APM with JSON OTLP export
Project description
fastapi_watchlog_apm
🔗 Website: https://watchlog.io
fastapi_watchlog_apm is a lightweight APM integration for FastAPI, built on OpenTelemetry. It provides:
- Auto‑instrumentation for FastAPI endpoints and underlying HTTP calls
- Manual custom spans via OpenTelemetry API
- OTLP exporters over HTTP (protobuf) for compact transport
- Environment detection (local vs in‑cluster Kubernetes)
- Configurable sampling, error‑only and slow‑only span export
- Metrics collection via OTLP
Installation
Install from PyPI:
pip install fastapi_apm_watchlog
Or directly from GitHub:
pip install git+https://github.com/Watchlog-monitoring/fastapi_apm_watchlog.git
Quick Start
Initialize the APM before mounting any routes:
# main.py
from fastapi import FastAPI
from fastapi_apm_watchlog import instrument
app = FastAPI()
# 1) Initialize Watchlog APM
instrument(
app,
service_name='my-fastapi-app', # your service name
error_tps=5, # max 5 error spans/sec
send_error_spans=True, # always send error spans
slow_threshold_ms=300, # always send spans >300ms
sample_rate=1.0 # random sample rate (0.0–1.0, capped at 0.3)
)
# 2) Define your routes
@app.get('/')
async def read_root():
return {'message': 'Hello Watchlog APM + FastAPI'}
# 3) Run your app
# uvicorn main:app --reload
What happens?
- FastAPI and HTTP calls are auto‑instrumented for tracing.
- Spans and metrics are exported to the Watchlog agent (local or Kubernetes).
- Custom filter rules (error‑only, slow‑only, sampling) apply.
Configuration Options
| Parameter | Type | Default | Description |
|---|---|---|---|
service_name |
str |
required | Name of your FastAPI 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 |
Max spans per batch |
batch_delay_ms |
int |
5000 |
Delay (ms) between batch exports |
metric_interval_ms |
int |
5000 |
Interval (ms) for metric export |
sample_rate |
float |
1.0 |
Random sampling rate (0.0–1.0, capped at 0.3) |
send_error_spans |
bool |
False |
If True, always export spans with non-UNSET 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) |
Manual Custom Spans
Leverage OpenTelemetry API for custom instrumentation:
from opentelemetry import trace
@app.get('/db')
async def fetch_db():
tracer = trace.get_tracer('watchlog-apm', '1.0.0')
span = tracer.start_span('db.query', attributes={'db.system':'postgresql'})
try:
# Execute your DB logic
result = await run_query()
return result
except Exception as e:
span.record_exception(e)
raise
finally:
span.end()
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:
- Kubernetes ServiceAccount token file
/proc/1/cgroupforkubepods- DNS lookup of
kubernetes.default.svc.cluster.local
Manual Override: You can override the endpoint by passing otlp_endpoint option in instrument() function
Docker Setup
When running your FastAPI app in Docker, you need to configure the correct agent endpoint.
Using otlp_endpoint Option (Recommended for Docker)
# main.py
from fastapi import FastAPI
from fastapi_apm_watchlog import instrument
app = FastAPI()
# Initialize Watchlog APM with explicit agent URL for Docker
instrument(
app,
service_name='my-fastapi-app',
otlp_endpoint='http://watchlog-agent:3774/apm', # Use container name
error_tps=5,
send_error_spans=True,
slow_threshold_ms=300,
sample_rate=1.0
)
@app.get('/')
async def read_root():
return {'message': 'Hello Watchlog APM + FastAPI'}
# Run: uvicorn main:app --reload
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
fastapi-app:
build: .
container_name: fastapi-app
ports:
- "8000:8000"
environment:
- PYTHONUNBUFFERED=1
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 FastAPI app (make sure your code sets otlp_endpoint='http://watchlog-agent:3774/apm')
docker run -d \
--name fastapi-app \
--network app-network \
-p 8000:8000 \
my-fastapi-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# fastapi_apm_watchlog
Project details
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 fastapi_apm_watchlog-1.1.0.tar.gz.
File metadata
- Download URL: fastapi_apm_watchlog-1.1.0.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
491e44e0743bfe58df6a841353932534af55f3b2f12d6b9f4c93aec25bc11a54
|
|
| MD5 |
2ba742f4e8b420dda5888e5b1c5a5416
|
|
| BLAKE2b-256 |
c4c5c2d87032cc23ef34ac879f2c2d789566f253c731191f4c1541669acb7393
|