or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

ai-monitoring.mdconfiguration.mdcontext-metadata.mdcron-monitoring.mdevent-capture.mdindex.mdintegrations.mdperformance-monitoring.mdprofiling.mdscope-management.mdstructured-logging.md

performance-monitoring.mddocs/

0

# Performance Monitoring

1

2

Distributed tracing with transactions and spans for monitoring application performance, database queries, external service calls, and custom operations with automatic and manual instrumentation support.

3

4

## Capabilities

5

6

### Transaction Management

7

8

Create and manage top-level transactions representing complete operations like HTTP requests, background jobs, or business processes.

9

10

```python { .api }

11

def start_transaction(

12

transaction: Optional[Union[Transaction, Dict[str, Any]]] = None,

13

instrumenter: str = INSTRUMENTER.SENTRY,

14

custom_sampling_context: Optional[Dict[str, Any]] = None,

15

**kwargs

16

) -> Union[Transaction, NoOpSpan]:

17

"""

18

Start a new transaction for performance monitoring.

19

20

Parameters:

21

- transaction: Transaction name or transaction object

22

- instrumenter: Instrumentation source identifier

23

- custom_sampling_context: Additional context for sampling decisions

24

- **kwargs: Additional transaction properties (op, description, source, etc.)

25

26

Returns:

27

Transaction or NoOpSpan: Active transaction or no-op if disabled/sampled out

28

"""

29

```

30

31

**Usage Examples:**

32

33

```python

34

import sentry_sdk

35

36

# Simple transaction

37

with sentry_sdk.start_transaction(name="process_order", op="function") as transaction:

38

# Process order logic

39

validate_order()

40

charge_payment()

41

fulfill_order()

42

43

# Transaction with custom properties

44

transaction = sentry_sdk.start_transaction(

45

name="data_pipeline",

46

op="task",

47

description="Process daily analytics batch",

48

source="custom",

49

data={"batch_size": 1000, "source": "analytics_db"}

50

)

51

try:

52

process_analytics_batch()

53

finally:

54

transaction.finish()

55

56

# HTTP request transaction (typically handled by web framework integrations)

57

def handle_api_request(request):

58

with sentry_sdk.start_transaction(

59

name=f"{request.method} {request.path}",

60

op="http.server",

61

source="route"

62

) as transaction:

63

transaction.set_tag("http.method", request.method)

64

transaction.set_tag("endpoint", request.path)

65

return process_request(request)

66

```

67

68

### Span Creation

69

70

Create child spans within transactions to measure specific operations like database queries, API calls, or computational tasks.

71

72

```python { .api }

73

def start_span(

74

instrumenter: str = INSTRUMENTER.SENTRY,

75

**kwargs

76

) -> Span:

77

"""

78

Start a new span within the current transaction.

79

80

Parameters:

81

- instrumenter: Instrumentation source identifier

82

- **kwargs: Span properties (op, description, tags, data, etc.)

83

84

Returns:

85

Span: Active span for the operation

86

"""

87

```

88

89

**Usage Examples:**

90

91

```python

92

import sentry_sdk

93

94

def process_user_data(user_id):

95

with sentry_sdk.start_transaction(name="process_user_data", op="function"):

96

# Database query span

97

with sentry_sdk.start_span(op="db.query", description="fetch user") as span:

98

span.set_tag("db.table", "users")

99

span.set_data("user_id", user_id)

100

user = database.get_user(user_id)

101

102

# API call span

103

with sentry_sdk.start_span(

104

op="http.client",

105

description="POST /api/enrichment"

106

) as span:

107

span.set_tag("http.method", "POST")

108

span.set_data("url", "https://api.example.com/enrichment")

109

enriched_data = api_client.enrich_user_data(user)

110

111

# Processing span

112

with sentry_sdk.start_span(op="function", description="transform_data"):

113

result = transform_user_data(enriched_data)

114

115

return result

116

```

117

118

### Active Span Access

119

120

Get the currently active span for adding metadata, measurements, or creating child spans.

121

122

```python { .api }

123

def get_current_span(scope: Optional[Scope] = None) -> Optional[Span]:

124

"""

125

Get the currently active span.

126

127

Parameters:

128

- scope: Scope to check for active span (uses current scope if None)

129

130

Returns:

131

Optional[Span]: Current span if active, None otherwise

132

"""

133

```

134

135

**Usage Examples:**

136

137

```python

138

import sentry_sdk

139

140

def database_operation(query):

141

span = sentry_sdk.get_current_span()

142

if span:

143

span.set_tag("db.system", "postgresql")

144

span.set_data("db.statement", query)

145

span.set_data("db.operation", "select")

146

147

return execute_query(query)

148

149

def add_custom_measurements():

150

span = sentry_sdk.get_current_span()

151

if span:

152

span.set_measurement("memory_usage_mb", get_memory_usage(), "megabyte")

153

span.set_measurement("cpu_usage_percent", get_cpu_usage(), "percent")

154

span.set_data("custom_metric", calculate_business_metric())

155

```

156

157

### Distributed Tracing

158

159

Connect traces across service boundaries using W3C Trace Context headers for distributed system monitoring.

160

161

```python { .api }

162

def continue_trace(

163

environ_or_headers: Union[Dict[str, str], Dict[str, Any]],

164

op: Optional[str] = None,

165

name: Optional[str] = None,

166

source: Optional[str] = None,

167

origin: str = "manual"

168

) -> Transaction:

169

"""

170

Continue a distributed trace from incoming headers.

171

172

Parameters:

173

- environ_or_headers: WSGI environ dict or HTTP headers dict

174

- op: Transaction operation type

175

- name: Transaction name

176

- source: Transaction source identifier

177

- origin: Trace origin identifier

178

179

Returns:

180

Transaction: Connected transaction continuing the distributed trace

181

"""

182

183

def get_traceparent() -> Optional[str]:

184

"""

185

Get W3C traceparent header value for outgoing requests.

186

187

Returns:

188

Optional[str]: Traceparent header value or None if no active transaction

189

"""

190

191

def get_baggage() -> Optional[str]:

192

"""

193

Get W3C baggage header value for outgoing requests.

194

195

Returns:

196

Optional[str]: Baggage header value or None if no baggage data

197

"""

198

```

199

200

**Usage Examples:**

201

202

```python

203

import sentry_sdk

204

import requests

205

206

# Server: Continue trace from incoming request

207

def handle_incoming_request(request):

208

# Extract trace context from headers

209

transaction = sentry_sdk.continue_trace(

210

request.headers,

211

op="http.server",

212

name=f"{request.method} {request.path}",

213

source="route"

214

)

215

216

with transaction:

217

return process_request(request)

218

219

# Client: Propagate trace to outgoing request

220

def make_api_call(url, data):

221

headers = {}

222

223

# Add trace headers for distributed tracing

224

if traceparent := sentry_sdk.get_traceparent():

225

headers["traceparent"] = traceparent

226

227

if baggage := sentry_sdk.get_baggage():

228

headers["baggage"] = baggage

229

230

with sentry_sdk.start_span(op="http.client", description=f"POST {url}"):

231

response = requests.post(url, json=data, headers=headers)

232

return response.json()

233

```

234

235

### Automatic Tracing Decorator

236

237

Automatically create spans for function calls using the trace decorator.

238

239

```python { .api }

240

def trace(func: Callable) -> Callable:

241

"""

242

Decorator to automatically create spans for function calls.

243

244

The span will use the function name as description and 'function' as operation.

245

Additional span data can be set within the decorated function.

246

247

Parameters:

248

- func: Function to wrap with automatic tracing

249

250

Returns:

251

Callable: Decorated function that creates spans automatically

252

"""

253

```

254

255

**Usage Examples:**

256

257

```python

258

import sentry_sdk

259

260

@sentry_sdk.trace

261

def process_payment(amount, currency):

262

"""This function will automatically create a span."""

263

# Add custom span data

264

span = sentry_sdk.get_current_span()

265

if span:

266

span.set_tag("payment.currency", currency)

267

span.set_data("payment.amount", amount)

268

269

return payment_processor.charge(amount, currency)

270

271

@sentry_sdk.trace

272

def calculate_analytics(dataset):

273

"""Complex calculation with automatic timing."""

274

span = sentry_sdk.get_current_span()

275

if span:

276

span.set_data("dataset_size", len(dataset))

277

span.set_tag("operation", "analytics")

278

279

result = perform_complex_calculation(dataset)

280

281

if span:

282

span.set_data("result_count", len(result))

283

284

return result

285

286

# Usage in transaction context

287

def process_order(order_id):

288

with sentry_sdk.start_transaction(name="process_order", op="function"):

289

payment_result = process_payment(100.0, "USD") # Automatically traced

290

analytics = calculate_analytics(order_data) # Automatically traced

291

return finalize_order(order_id, payment_result)

292

```

293

294

### Span Modification

295

296

Update properties of the currently active span without needing a direct reference to the span object.

297

298

```python { .api }

299

def update_current_span(

300

op: Optional[str] = None,

301

name: Optional[str] = None,

302

attributes: Optional[Dict[str, Union[str, int, float, bool]]] = None,

303

data: Optional[Dict[str, Any]] = None # Deprecated

304

) -> None:

305

"""

306

Update the current active span with the provided parameters.

307

308

Parameters:

309

- op: The operation name for the span (e.g., "http.client", "db.query")

310

- name: The human-readable name/description for the span

311

- attributes: Key-value pairs to add as attributes to the span

312

- data: Deprecated, use attributes instead

313

"""

314

```

315

316

**Usage Examples:**

317

318

```python

319

import sentry_sdk

320

from sentry_sdk.consts import OP

321

322

# Start a span and update it later

323

with sentry_sdk.start_span(op="function", name="process_data") as span:

324

user_id = get_user_id()

325

326

# Update span with additional context as we learn more

327

sentry_sdk.update_current_span(

328

name=f"process_data_for_user_{user_id}",

329

attributes={

330

"user_id": user_id,

331

"batch_size": 50,

332

"processing_type": "standard"

333

}

334

)

335

336

# Process data...

337

result = expensive_operation()

338

339

# Update with results

340

sentry_sdk.update_current_span(

341

attributes={

342

"result_count": len(result),

343

"success": True

344

}

345

)

346

```

347

348

## Span Interface

349

350

### Span Properties and Methods

351

352

```python { .api }

353

class Span:

354

def set_tag(self, key: str, value: str) -> None:

355

"""Set a tag on the span."""

356

357

def set_data(self, key: str, value: Any) -> None:

358

"""Set structured data on the span."""

359

360

def set_measurement(self, name: str, value: float, unit: str = "") -> None:

361

"""Set a performance measurement."""

362

363

def set_status(self, status: str) -> None:

364

"""Set span status ('ok', 'cancelled', 'internal_error', etc.)."""

365

366

def set_http_status(self, http_status: int) -> None:

367

"""Set HTTP status code and derive span status."""

368

369

def finish(self, end_timestamp: Optional[datetime] = None) -> None:

370

"""Finish the span with optional custom end time."""

371

372

def to_json(self) -> Dict[str, Any]:

373

"""Serialize span to JSON representation."""

374

375

@property

376

def span_id(self) -> str:

377

"""Unique span identifier."""

378

379

@property

380

def trace_id(self) -> str:

381

"""Trace identifier shared across distributed trace."""

382

383

@property

384

def parent_span_id(self) -> Optional[str]:

385

"""Parent span identifier."""

386

387

@property

388

def sampled(self) -> Optional[bool]:

389

"""Whether this span is sampled for tracing."""

390

```

391

392

### Transaction-Specific Interface

393

394

```python { .api }

395

class Transaction(Span):

396

def set_name(self, name: str, source: Optional[str] = None) -> None:

397

"""Set transaction name and source."""

398

399

@property

400

def name(self) -> str:

401

"""Transaction name."""

402

403

@property

404

def source(self) -> str:

405

"""Transaction source ('custom', 'route', 'url', etc.)."""

406

```

407

408

## Performance Data

409

410

### Automatic Measurements

411

412

The SDK automatically collects:

413

- **Span duration**: Start and end timestamps

414

- **HTTP metrics**: Status codes, response sizes, request/response times

415

- **Database metrics**: Query timing, connection info, affected rows

416

- **Cache metrics**: Hit/miss ratios, operation timing

417

- **Queue metrics**: Job processing time, queue depth

418

419

### Custom Measurements

420

421

Add custom performance measurements:

422

423

```python

424

span = sentry_sdk.get_current_span()

425

if span:

426

# Time-based measurements

427

span.set_measurement("processing_time", 142.5, "millisecond")

428

span.set_measurement("wait_time", 2.3, "second")

429

430

# Size measurements

431

span.set_measurement("payload_size", 1024, "byte")

432

span.set_measurement("result_count", 50, "none")

433

434

# Rate measurements

435

span.set_measurement("throughput", 1500, "per_second")

436

span.set_measurement("error_rate", 0.02, "ratio")

437

```

438

439

## Integration with Scopes

440

441

Performance monitoring integrates with scope management:

442

- Transactions and spans inherit scope context (tags, user, extra data)

443

- Performance events include breadcrumbs and contextual information

444

- Scope modifications during spans affect the span's metadata

445

- Automatic correlation between errors and performance data