0
# Profiling
1
2
CPU profiling capabilities for performance analysis with support for different scheduling backends, continuous profiling, transaction-based profiling, and comprehensive performance data collection.
3
4
## Capabilities
5
6
### Profile Session Management
7
8
Control profiling sessions with start/stop functions for manual profiling control and custom profiling workflows.
9
10
```python { .api }
11
def start_profiler() -> None:
12
"""
13
Start a profiling session for the current process.
14
15
Begins CPU profiling using the configured profiler backend.
16
Must be called before any profiled operations.
17
"""
18
19
def stop_profiler() -> None:
20
"""
21
Stop the current profiling session.
22
23
Ends CPU profiling and processes collected profile data.
24
Should be called after profiled operations complete.
25
"""
26
27
# Alternative names for compatibility
28
def start_profile_session() -> None:
29
"""Alias for start_profiler()."""
30
31
def stop_profile_session() -> None:
32
"""Alias for stop_profiler()."""
33
```
34
35
**Usage Examples:**
36
37
```python
38
import sentry_sdk
39
40
# Initialize SDK with profiling enabled
41
sentry_sdk.init(
42
dsn="your-dsn-here",
43
profiles_sample_rate=1.0, # Profile 100% of transactions
44
)
45
46
# Manual profiling session
47
sentry_sdk.start_profiler()
48
try:
49
# Code to profile
50
perform_cpu_intensive_task()
51
process_large_dataset()
52
complex_algorithm()
53
finally:
54
sentry_sdk.stop_profiler()
55
56
# Profiling with transaction context
57
with sentry_sdk.start_transaction(name="batch_processing", op="task"):
58
sentry_sdk.start_profiler()
59
try:
60
process_batch_job()
61
finally:
62
sentry_sdk.stop_profiler()
63
```
64
65
### Transaction-Based Profiling
66
67
Automatic profiling within transactions when profiling is enabled through sampling configuration.
68
69
```python { .api }
70
class Profile:
71
def __init__(self, transaction: Transaction):
72
"""
73
Create a profile associated with a transaction.
74
75
Parameters:
76
- transaction: Transaction to associate profile data with
77
"""
78
79
def finish(self) -> None:
80
"""
81
Finish the profile and send data to Sentry.
82
83
Processes collected profiling data and associates it with
84
the transaction for performance analysis.
85
"""
86
```
87
88
**Usage Examples:**
89
90
```python
91
import sentry_sdk
92
93
# Automatic profiling through sampling
94
sentry_sdk.init(
95
dsn="your-dsn-here",
96
traces_sample_rate=1.0, # Sample all transactions
97
profiles_sample_rate=0.1, # Profile 10% of sampled transactions
98
)
99
100
def cpu_intensive_function():
101
# This function will be automatically profiled
102
# when called within a sampled transaction
103
for i in range(1000000):
104
complex_calculation(i)
105
106
# Transaction with automatic profiling
107
with sentry_sdk.start_transaction(name="data_processing", op="function") as transaction:
108
# If this transaction is selected for profiling,
109
# all function calls will be profiled automatically
110
load_data()
111
cpu_intensive_function() # Profile data collected here
112
save_results()
113
114
# Manual profile management within transaction
115
def manual_profiling_example():
116
with sentry_sdk.start_transaction(name="manual_profile", op="task") as transaction:
117
# Create explicit profile instance
118
profile = sentry_sdk.profiler.Profile(transaction)
119
120
try:
121
# Operations to profile
122
expensive_operation_1()
123
expensive_operation_2()
124
finally:
125
# Finish profile and send data
126
profile.finish()
127
```
128
129
## Profiler Scheduling Backends
130
131
### Available Schedulers
132
133
Different profiler schedulers for various runtime environments and use cases.
134
135
```python { .api }
136
class ThreadScheduler:
137
"""Thread-based profiling scheduler for standard Python applications."""
138
def __init__(self, frequency: int = 101): ...
139
140
class GeventScheduler:
141
"""Gevent-compatible profiling scheduler for gevent applications."""
142
def __init__(self, frequency: int = 101): ...
143
144
class SleepScheduler:
145
"""Sleep-based profiling scheduler for minimal overhead profiling."""
146
def __init__(self, frequency: int = 101): ...
147
```
148
149
**Configuration Examples:**
150
151
```python
152
import sentry_sdk
153
from sentry_sdk.profiler import ThreadScheduler, GeventScheduler
154
155
# Configure profiler for standard threading
156
sentry_sdk.init(
157
dsn="your-dsn-here",
158
profiles_sample_rate=0.1,
159
_experiments={
160
"profiler_scheduler": ThreadScheduler(frequency=101) # 101 Hz sampling
161
}
162
)
163
164
# Configure profiler for gevent applications
165
import gevent
166
sentry_sdk.init(
167
dsn="your-dsn-here",
168
profiles_sample_rate=0.2,
169
_experiments={
170
"profiler_scheduler": GeventScheduler(frequency=201) # 201 Hz sampling
171
}
172
)
173
```
174
175
### Continuous Profiling
176
177
Background profiling that runs continuously throughout application lifetime.
178
179
```python
180
import sentry_sdk
181
182
# Enable continuous profiling
183
sentry_sdk.init(
184
dsn="your-dsn-here",
185
profiles_sample_rate=1.0,
186
_experiments={
187
"continuous_profiling_auto_start": True,
188
"profiler_mode": "continuous"
189
}
190
)
191
192
# Continuous profiling runs automatically in the background
193
# No manual start/stop required
194
def application_code():
195
while True:
196
handle_request() # Profiled continuously
197
process_background_tasks() # Profiled continuously
198
time.sleep(1)
199
```
200
201
## Profiling Configuration
202
203
### Sampling Configuration
204
205
Control when and how often profiling occurs through sampling rates and custom sampling functions.
206
207
```python
208
import sentry_sdk
209
210
# Percentage-based sampling
211
sentry_sdk.init(
212
dsn="your-dsn-here",
213
traces_sample_rate=1.0, # Sample all transactions
214
profiles_sample_rate=0.1, # Profile 10% of transactions
215
)
216
217
# Custom profiling sampler
218
def custom_profiles_sampler(sampling_context):
219
"""Custom logic for profiling sampling decisions."""
220
# Profile all transactions in development
221
if sampling_context.get("environment") == "development":
222
return 1.0
223
224
# Profile high-value operations
225
if sampling_context.get("transaction_context", {}).get("name", "").startswith("critical_"):
226
return 0.5
227
228
# Light profiling for regular operations
229
return 0.05
230
231
sentry_sdk.init(
232
dsn="your-dsn-here",
233
traces_sample_rate=0.1,
234
profiles_sampler=custom_profiles_sampler
235
)
236
```
237
238
### Performance Impact Control
239
240
Configure profiling to minimize performance impact on production applications.
241
242
```python
243
import sentry_sdk
244
245
# Low-impact production profiling
246
sentry_sdk.init(
247
dsn="your-dsn-here",
248
traces_sample_rate=0.01, # Sample 1% of transactions
249
profiles_sample_rate=0.1, # Profile 10% of sampled transactions = 0.1% total
250
_experiments={
251
"profiler_scheduler_frequency": 51, # Lower frequency = less overhead
252
"max_profile_duration_ms": 30000, # 30 second max profile duration
253
"profile_timeout_warning": True # Warn on long profiles
254
}
255
)
256
257
# High-detail development profiling
258
sentry_sdk.init(
259
dsn="your-dsn-here",
260
traces_sample_rate=1.0, # Sample all transactions
261
profiles_sample_rate=1.0, # Profile all transactions
262
_experiments={
263
"profiler_scheduler_frequency": 1001, # High frequency sampling
264
"max_profile_duration_ms": 300000, # 5 minute max duration
265
"include_local_variables": True # Include variable values
266
}
267
)
268
```
269
270
## Advanced Profiling Usage
271
272
### Custom Profiling Contexts
273
274
Combine profiling with custom contexts for targeted performance analysis.
275
276
```python
277
import sentry_sdk
278
279
def profile_critical_path(operation_name, **context):
280
"""Context manager for profiling critical code paths."""
281
with sentry_sdk.start_transaction(
282
name=operation_name,
283
op="performance_analysis"
284
) as transaction:
285
286
# Add profiling context
287
transaction.set_tag("profiling_target", "critical_path")
288
for key, value in context.items():
289
transaction.set_data(key, value)
290
291
# Force profiling for this transaction
292
sentry_sdk.start_profiler()
293
try:
294
yield transaction
295
finally:
296
sentry_sdk.stop_profiler()
297
298
# Usage
299
with profile_critical_path("payment_processing",
300
user_tier="premium",
301
amount=1000.0) as transaction:
302
303
validate_payment_data() # Profiled
304
process_payment() # Profiled
305
update_user_account() # Profiled
306
send_confirmation() # Profiled
307
```
308
309
### Performance Regression Detection
310
311
Use profiling data to detect performance regressions and optimize hot paths.
312
313
```python
314
import sentry_sdk
315
import time
316
317
def benchmark_function(func, iterations=1000):
318
"""Benchmark a function with profiling data."""
319
with sentry_sdk.start_transaction(
320
name=f"benchmark_{func.__name__}",
321
op="benchmark"
322
) as transaction:
323
324
transaction.set_data("iterations", iterations)
325
transaction.set_tag("benchmark_type", "performance_test")
326
327
sentry_sdk.start_profiler()
328
start_time = time.time()
329
330
try:
331
for i in range(iterations):
332
result = func()
333
334
end_time = time.time()
335
total_time = end_time - start_time
336
avg_time = total_time / iterations
337
338
transaction.set_measurement("total_time", total_time, "second")
339
transaction.set_measurement("avg_time_per_call", avg_time * 1000, "millisecond")
340
transaction.set_measurement("calls_per_second", iterations / total_time, "per_second")
341
342
return {
343
"total_time": total_time,
344
"avg_time": avg_time,
345
"calls_per_second": iterations / total_time
346
}
347
348
finally:
349
sentry_sdk.stop_profiler()
350
351
# Usage
352
def cpu_bound_function():
353
return sum(i * i for i in range(10000))
354
355
# Benchmark with profiling
356
results = benchmark_function(cpu_bound_function, iterations=100)
357
print(f"Average time per call: {results['avg_time']*1000:.2f}ms")
358
```
359
360
### Integration with Performance Monitoring
361
362
Combine profiling with transaction and span data for comprehensive performance analysis.
363
364
```python
365
import sentry_sdk
366
367
def analyze_database_performance():
368
"""Profile database operations with detailed span data."""
369
with sentry_sdk.start_transaction(
370
name="database_analysis",
371
op="performance.database"
372
) as transaction:
373
374
sentry_sdk.start_profiler()
375
376
try:
377
# Profile individual database operations
378
with sentry_sdk.start_span(op="db.query", description="user_lookup") as span:
379
span.set_data("query", "SELECT * FROM users WHERE active = true")
380
users = database.get_active_users() # Profiled
381
span.set_data("row_count", len(users))
382
383
with sentry_sdk.start_span(op="db.bulk_insert", description="activity_log") as span:
384
span.set_data("operation", "bulk_insert")
385
activities = []
386
for user in users:
387
activities.append(create_activity_record(user)) # Profiled
388
database.bulk_insert_activities(activities) # Profiled
389
span.set_data("insert_count", len(activities))
390
391
with sentry_sdk.start_span(op="db.query", description="aggregate_stats") as span:
392
span.set_data("query", "SELECT COUNT(*), AVG(score) FROM user_stats")
393
stats = database.get_aggregate_stats() # Profiled
394
span.set_data("aggregation_result", stats)
395
396
finally:
397
sentry_sdk.stop_profiler()
398
399
return {"user_count": len(users), "stats": stats}
400
```
401
402
## Profiling Best Practices
403
404
### Production Guidelines
405
406
- **Low sampling rates**: Use 1-10% profiling sampling in production
407
- **Time limits**: Set reasonable `max_profile_duration_ms` to prevent long-running profiles
408
- **Resource monitoring**: Monitor CPU and memory impact of profiling
409
- **Selective profiling**: Profile only critical code paths in production
410
411
### Development and Testing
412
413
- **High sampling**: Use 100% profiling sampling for development analysis
414
- **Comprehensive coverage**: Profile all major code paths during testing
415
- **Baseline establishment**: Create performance baselines for regression detection
416
- **Hot path identification**: Use profiling to identify CPU-intensive operations
417
418
### Performance Optimization Workflow
419
420
1. **Identify bottlenecks**: Use profiling to find slow functions
421
2. **Measure improvements**: Profile before and after optimizations
422
3. **Regression testing**: Continuous profiling to catch performance regressions
423
4. **Resource usage**: Monitor profiling overhead and adjust sampling rates
424
5. **Long-term trends**: Analyze profiling data over time for performance trends
425
426
Profiling provides deep insights into application performance with flexible configuration options for development, testing, and production environments.