or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-security.mdautomatic-instrumentation.mdconfiguration-settings.mdcore-tracing.mdindex.mdopentelemetry-integration.mdprofiling.md

automatic-instrumentation.mddocs/

0

# Automatic Instrumentation

1

2

Comprehensive automatic instrumentation for web frameworks, databases, HTTP clients, message queues, AI/ML libraries, and 80+ other popular Python packages through sophisticated monkey-patching. This enables zero-code-change observability for most Python applications.

3

4

## Capabilities

5

6

### Manual Patching

7

8

Selective instrumentation of specific libraries and frameworks for precise control over which components are monitored.

9

10

```python { .api }

11

def patch(

12

# Web Frameworks

13

django: bool = None,

14

flask: bool = None,

15

fastapi: bool = None,

16

sanic: bool = None,

17

bottle: bool = None,

18

molten: bool = None,

19

pyramid: bool = None,

20

tornado: bool = None,

21

aiohttp: bool = None,

22

23

# Databases

24

psycopg: bool = None,

25

mysql: bool = None,

26

mysqldb: bool = None,

27

pymysql: bool = None,

28

sqlite3: bool = None,

29

pymongo: bool = None,

30

mongoengine: bool = None,

31

cassandra: bool = None,

32

33

# Caching

34

redis: bool = None,

35

rediscluster: bool = None,

36

aioredis: bool = None,

37

aredis: bool = None,

38

pymemcache: bool = None,

39

40

# HTTP Clients

41

requests: bool = None,

42

httpx: bool = None,

43

httplib: bool = None,

44

urllib3: bool = None,

45

46

# AWS Services

47

boto: bool = None,

48

botocore: bool = None,

49

aiobotocore: bool = None,

50

51

# Message Queues

52

celery: bool = None,

53

kombu: bool = None,

54

dramatiq: bool = None,

55

rq: bool = None,

56

57

# Search

58

elasticsearch: bool = None,

59

algoliasearch: bool = None,

60

61

# AI/ML Libraries

62

openai: bool = None,

63

anthropic: bool = None,

64

langchain: bool = None,

65

langgraph: bool = None,

66

google_genai: bool = None,

67

google_generativeai: bool = None,

68

litellm: bool = None,

69

70

# Testing

71

pytest: bool = None,

72

pytest_bdd: bool = None,

73

pytest_benchmark: bool = None,

74

75

# Async

76

asyncio: bool = None,

77

gevent: bool = None,

78

79

# Other

80

grpc: bool = None,

81

graphql: bool = None,

82

jinja2: bool = None,

83

mako: bool = None,

84

protobuf: bool = None,

85

avro: bool = None,

86

87

# Configuration

88

raise_errors: bool = True,

89

**kwargs

90

) -> None:

91

"""

92

Manually patch specific modules for automatic instrumentation.

93

94

Parameters:

95

- Library-specific boolean flags to enable/disable instrumentation

96

- raise_errors: Whether to raise exceptions if patching fails (default: True)

97

- **kwargs: Additional library flags not explicitly listed

98

99

Raises:

100

- ModuleNotFoundException: If a requested module doesn't have instrumentation

101

- ImportError: If a requested module isn't installed

102

"""

103

```

104

105

Usage examples:

106

107

```python

108

from ddtrace import patch

109

110

# Patch specific components for a web application

111

patch(

112

django=True, # Django web framework

113

psycopg=True, # PostgreSQL database

114

redis=True, # Redis caching

115

requests=True, # HTTP client

116

celery=True # Background tasks

117

)

118

119

# Patch AI/ML components for an AI application

120

patch(

121

fastapi=True, # API framework

122

openai=True, # OpenAI integration

123

langchain=True, # LangChain framework

124

pymongo=True # MongoDB database

125

)

126

127

# Minimal patching for microservice

128

patch(flask=True, requests=True)

129

130

# Error handling

131

try:

132

patch(nonexistent_library=True)

133

except ModuleNotFoundException as e:

134

print(f"Library not supported: {e}")

135

except ImportError as e:

136

print(f"Library not installed: {e}")

137

```

138

139

### Deprecated Bulk Patching

140

141

```python { .api }

142

def patch_all(**patch_modules: bool) -> None:

143

"""

144

Automatically patch all supported modules (deprecated).

145

146

Parameters:

147

- **patch_modules: Override flags for specific modules

148

149

Note: This function is deprecated in favor of patch() and DD_PATCH_MODULES

150

environment variable. It will be removed in a future version.

151

"""

152

```

153

154

### Environment-Based Configuration

155

156

Configure automatic instrumentation through environment variables for deployment flexibility.

157

158

```python

159

import os

160

161

# Enable instrumentation via environment variables

162

os.environ['DD_PATCH_MODULES'] = 'django:true,redis:true,psycopg:true'

163

164

# Or disable specific modules

165

os.environ['DD_PATCH_MODULES'] = 'django:true,redis:false,celery:true'

166

167

# Import ddtrace to apply environment-based patching

168

import ddtrace.auto # Automatically applies DD_PATCH_MODULES configuration

169

```

170

171

### Web Framework Integration

172

173

#### Django

174

175

Comprehensive Django integration covering ORM, middleware, templates, and admin interface.

176

177

```python

178

from ddtrace import patch

179

180

patch(django=True)

181

182

# Automatically instruments:

183

# - HTTP request/response handling

184

# - Database queries via Django ORM

185

# - Template rendering

186

# - Cache operations

187

# - Authentication and sessions

188

# - Admin interface interactions

189

# - Middleware processing

190

# - Static file serving

191

192

# Example Django view with automatic instrumentation

193

def user_profile(request, user_id):

194

# HTTP request is automatically traced

195

user = User.objects.get(id=user_id) # Database query traced

196

return render(request, 'profile.html', {'user': user}) # Template rendering traced

197

```

198

199

#### Flask

200

201

Flask application instrumentation including routes, templates, and extensions.

202

203

```python

204

from ddtrace import patch

205

from flask import Flask

206

207

patch(flask=True)

208

209

app = Flask(__name__)

210

211

# Automatically instruments:

212

# - Route handling and request processing

213

# - Template rendering (Jinja2)

214

# - Error handling

215

# - Before/after request hooks

216

# - Blueprint operations

217

# - Session management

218

219

@app.route('/api/users/<int:user_id>')

220

def get_user(user_id):

221

# Route automatically traced with URL pattern

222

user_data = fetch_user_from_db(user_id) # If DB is patched, this is traced too

223

return jsonify(user_data)

224

```

225

226

#### FastAPI

227

228

Modern async API framework instrumentation with automatic OpenAPI integration.

229

230

```python

231

from ddtrace import patch

232

from fastapi import FastAPI

233

234

patch(fastapi=True)

235

236

app = FastAPI()

237

238

# Automatically instruments:

239

# - Async request handling

240

# - Path parameters and query parameters

241

# - Request/response serialization

242

# - Dependency injection

243

# - Background tasks

244

# - WebSocket connections

245

# - OpenAPI documentation generation

246

247

@app.post("/items/")

248

async def create_item(item: ItemModel):

249

# Async endpoint automatically traced

250

result = await save_item_to_db(item) # Async DB operation traced

251

return result

252

```

253

254

### Database Integration

255

256

#### PostgreSQL (psycopg2/psycopg3)

257

258

```python

259

from ddtrace import patch

260

261

patch(psycopg=True)

262

263

# Automatically instruments:

264

# - SQL query execution

265

# - Connection pooling

266

# - Transaction management

267

# - Cursor operations

268

# - Prepared statements

269

270

import psycopg2

271

272

conn = psycopg2.connect("dbname=mydb user=myuser")

273

cursor = conn.cursor()

274

275

# This query is automatically traced with SQL statement and parameters

276

cursor.execute("SELECT * FROM users WHERE age > %s", (25,))

277

results = cursor.fetchall()

278

```

279

280

#### MongoDB

281

282

```python

283

from ddtrace import patch

284

285

patch(pymongo=True, mongoengine=True)

286

287

# PyMongo instrumentation

288

from pymongo import MongoClient

289

290

client = MongoClient('mongodb://localhost:27017/')

291

db = client.mydb

292

293

# Collection operations automatically traced

294

users = db.users.find({"age": {"$gt": 25}})

295

296

# MongoEngine instrumentation

297

from mongoengine import Document, StringField, IntField

298

299

class User(Document):

300

name = StringField(required=True)

301

age = IntField()

302

303

# ORM operations automatically traced

304

user = User.objects(age__gt=25).first()

305

```

306

307

#### Redis

308

309

```python

310

from ddtrace import patch

311

312

patch(redis=True, aioredis=True)

313

314

# Redis instrumentation

315

import redis

316

317

r = redis.Redis(host='localhost', port=6379, db=0)

318

319

# Cache operations automatically traced

320

r.set('user:123', 'john_doe')

321

username = r.get('user:123')

322

323

# Async Redis instrumentation

324

import aioredis

325

326

async def cache_operation():

327

redis_client = aioredis.from_url("redis://localhost")

328

await redis_client.set('async_key', 'value') # Traced

329

return await redis_client.get('async_key') # Traced

330

```

331

332

### HTTP Client Integration

333

334

#### Requests

335

336

```python

337

from ddtrace import patch

338

339

patch(requests=True)

340

341

import requests

342

343

# HTTP requests automatically traced with URL, method, status code

344

response = requests.get('https://api.example.com/users')

345

data = response.json()

346

347

# POST requests with request/response details

348

response = requests.post(

349

'https://api.example.com/users',

350

json={'name': 'John', 'email': 'john@example.com'}

351

)

352

```

353

354

#### HTTPX (Async HTTP)

355

356

```python

357

from ddtrace import patch

358

359

patch(httpx=True)

360

361

import httpx

362

363

# Sync client

364

with httpx.Client() as client:

365

response = client.get('https://api.example.com/data') # Traced

366

367

# Async client

368

async with httpx.AsyncClient() as client:

369

response = await client.get('https://api.example.com/data') # Traced

370

```

371

372

### AI/ML Library Integration

373

374

#### OpenAI

375

376

```python

377

from ddtrace import patch

378

379

patch(openai=True)

380

381

from openai import OpenAI

382

383

client = OpenAI()

384

385

# Chat completions automatically traced with token usage, model info

386

response = client.chat.completions.create(

387

model="gpt-3.5-turbo",

388

messages=[{"role": "user", "content": "Hello, world!"}]

389

)

390

391

# Embeddings and other operations also traced

392

embeddings = client.embeddings.create(

393

model="text-embedding-ada-002",

394

input="Text to embed"

395

)

396

```

397

398

#### LangChain

399

400

```python

401

from ddtrace import patch

402

403

patch(langchain=True)

404

405

# LangChain operations automatically traced

406

from langchain.llms import OpenAI

407

from langchain.chains import LLMChain

408

from langchain.prompts import PromptTemplate

409

410

llm = OpenAI()

411

prompt = PromptTemplate(template="Tell me about {topic}")

412

chain = LLMChain(llm=llm, prompt=prompt)

413

414

# Chain execution automatically traced with input/output

415

result = chain.run(topic="machine learning")

416

```

417

418

### Message Queue Integration

419

420

#### Celery

421

422

```python

423

from ddtrace import patch

424

425

patch(celery=True)

426

427

from celery import Celery

428

429

app = Celery('myapp', broker='redis://localhost:6379')

430

431

# Task definitions automatically instrumented

432

@app.task

433

def process_data(data_id):

434

# Task execution automatically traced

435

data = fetch_data(data_id)

436

return process_and_save(data)

437

438

# Task calls traced as both producer and consumer

439

result = process_data.delay('123')

440

```

441

442

### Testing Integration

443

444

#### pytest

445

446

```python

447

from ddtrace import patch

448

449

patch(pytest=True)

450

451

# Test execution automatically traced

452

# - Test discovery and collection

453

# - Individual test execution time

454

# - Test outcomes (pass/fail/skip)

455

# - Test parameters and fixtures

456

# - Coverage information (if available)

457

458

def test_user_creation():

459

# Test execution automatically traced

460

user = create_user("test@example.com")

461

assert user.email == "test@example.com"

462

463

@pytest.mark.parametrize("email", ["test1@example.com", "test2@example.com"])

464

def test_email_validation(email):

465

# Parameterized tests traced individually

466

assert validate_email(email)

467

```

468

469

### Advanced Configuration

470

471

#### Per-Integration Configuration

472

473

```python

474

from ddtrace import config, patch

475

476

# Configure before patching

477

config.django.service_name = "web-frontend"

478

config.redis.service_name = "cache-service"

479

config.psycopg.service_name = "database"

480

481

# Apply patches with custom configuration

482

patch(django=True, redis=True, psycopg=True)

483

```

484

485

#### Pin-based Configuration

486

487

```python

488

from ddtrace import Pin, patch

489

from ddtrace.contrib.redis import get_version

490

491

patch(redis=True)

492

493

import redis

494

495

# Customize Redis instrumentation

496

redis_client = redis.Redis()

497

pin = Pin.get_from(redis_client)

498

pin.clone(service="user-cache", tags={"cache.type": "user-data"}).onto(redis_client)

499

500

# Operations now use custom service name and tags

501

redis_client.set('user:123', 'data')

502

```

503

504

#### Global Tags and Service Mapping

505

506

```python

507

from ddtrace import config, patch

508

509

# Global configuration

510

config.service = "my-application"

511

config.env = "production"

512

config.version = "2.1.0"

513

514

# Service name mapping for integrations

515

config.service_mapping = {

516

'psycopg': 'postgres-primary',

517

'redis': 'redis-cache',

518

'requests': 'external-apis'

519

}

520

521

# Global tags applied to all spans

522

config.tags = {

523

'team': 'backend',

524

'region': 'us-east-1'

525

}

526

527

patch(psycopg=True, redis=True, requests=True)

528

```

529

530

### Error Handling and Debugging

531

532

```python

533

from ddtrace import patch

534

from ddtrace.contrib.integration_registry import ModuleNotFoundException

535

536

try:

537

patch(

538

django=True,

539

nonexistent_lib=True, # This will fail

540

raise_errors=True

541

)

542

except ModuleNotFoundException as e:

543

print(f"Integration not available: {e}")

544

# Continue with available integrations

545

patch(django=True, raise_errors=False)

546

547

# Check which integrations are available

548

from ddtrace.contrib import trace_integrations

549

550

available_integrations = trace_integrations()

551

print(f"Available integrations: {list(available_integrations.keys())}")

552

```

553

554

### Performance Considerations

555

556

```python

557

# Selective patching for performance-critical applications

558

patch(

559

# Essential components only

560

flask=True,

561

psycopg=True,

562

redis=True,

563

564

# Skip expensive instrumentations if not needed

565

jinja2=False,

566

graphql=False

567

)

568

569

# Configure sampling for high-throughput applications

570

from ddtrace import config

571

572

config.analytics_enabled = False # Disable analytics if not needed

573

config.priority_sampling = True # Use priority sampling

574

```

575

576

## Supported Libraries

577

578

ddtrace provides automatic instrumentation for 80+ Python libraries organized by category:

579

580

### Web Frameworks

581

- Django, Flask, FastAPI, Sanic, Bottle, Molten, Pyramid, Tornado, aiohttp

582

583

### Databases

584

- PostgreSQL (psycopg2/3), MySQL, MongoDB, Redis, Cassandra, Elasticsearch

585

586

### HTTP Clients

587

- requests, httpx, urllib3, aiohttp

588

589

### AWS Services

590

- boto3, botocore, aiobotocore

591

592

### Message Queues

593

- Celery, Kombu, Dramatiq, RQ

594

595

### AI/ML

596

- OpenAI, Anthropic, LangChain, LangGraph, Google AI, LiteLLM

597

598

### Testing

599

- pytest, pytest-bdd, pytest-benchmark

600

601

### And Many More

602

- gRPC, GraphQL, Jinja2, Mako, Protobuf, Avro, asyncio, gevent, and others

603

604

Each integration captures relevant metadata, timing information, and error states specific to that library's operations.