or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

breadcrumb-system.mdcontext-management.mdcore-client.mddata-processing.mdframework-integrations.mdindex.mdlogging-integration.mdtransport-layer.md

context-management.mddocs/

0

# Context Management

1

2

Raven provides thread-local context management for maintaining user information, tags, extra data, and breadcrumbs that persist throughout the application lifecycle and are automatically included with events.

3

4

## Capabilities

5

6

### Context Class

7

8

Thread-local context storage for tags, extra data, and breadcrumbs.

9

10

```python { .api }

11

from raven.context import Context

12

13

class Context(local, Mapping, Iterable):

14

def __init__(self, client=None):

15

"""

16

Initialize context with empty data storage.

17

18

Parameters:

19

- client (Client): Associated Sentry client instance

20

"""

21

22

def activate(self, sticky=False):

23

"""

24

Activate context for current thread.

25

26

Parameters:

27

- sticky (bool): Keep context active after deactivation

28

"""

29

30

def deactivate(self):

31

"""Deactivate context for current thread."""

32

33

def merge(self, data, activate=True):

34

"""

35

Merge data into context.

36

37

Parameters:

38

- data (dict): Context data to merge

39

- activate (bool): Activate context after merging

40

41

Returns:

42

Context: Self for chaining

43

"""

44

45

def clear(self, deactivate=None):

46

"""

47

Clear context data.

48

49

Parameters:

50

- deactivate (bool): Whether to deactivate context

51

"""

52

53

def get(self):

54

"""

55

Get current context data.

56

57

Returns:

58

dict: Current context data

59

"""

60

61

def set(self, data):

62

"""

63

Set context data, replacing existing data.

64

65

Parameters:

66

- data (dict): Context data to set

67

"""

68

69

def __enter__(self):

70

"""Context manager entry - activates context."""

71

72

def __exit__(self, exc_type, exc_value, tb):

73

"""Context manager exit - deactivates context."""

74

75

def __getitem__(self, key):

76

"""Get context data by key (dict-like access)."""

77

78

def __iter__(self):

79

"""Iterate over context keys."""

80

81

def __len__(self):

82

"""Get number of context items."""

83

```

84

85

### Context Utilities

86

87

Functions for working with active contexts across threads.

88

89

```python { .api }

90

from raven.context import get_active_contexts

91

92

def get_active_contexts():

93

"""

94

Get all active contexts for current thread.

95

96

Returns:

97

list: List of active Context instances

98

"""

99

```

100

101

### Client Context Methods

102

103

Client methods for managing context data that gets included with events.

104

105

```python { .api }

106

# From Client class

107

def user_context(self, data):

108

"""

109

Set user context information.

110

111

Parameters:

112

- data (dict): User data including 'id', 'username', 'email', 'ip_address'

113

"""

114

115

def tags_context(self, data):

116

"""

117

Set tags for event categorization and filtering.

118

119

Parameters:

120

- data (dict): Tag key-value pairs

121

"""

122

123

def extra_context(self, data):

124

"""

125

Set extra context data for debugging.

126

127

Parameters:

128

- data (dict): Additional context information

129

"""

130

131

def http_context(self, data):

132

"""

133

Set HTTP request context.

134

135

Parameters:

136

- data (dict): HTTP context including 'url', 'method', 'headers', 'query_string'

137

"""

138

```

139

140

## Usage Examples

141

142

### Basic Context Usage

143

144

```python

145

from raven import Client

146

from raven.context import Context

147

148

client = Client('https://your-dsn@sentry.io/project-id')

149

150

# Set user context

151

client.user_context({

152

'id': 123,

153

'username': 'john_doe',

154

'email': 'john@example.com',

155

'ip_address': '192.168.1.1'

156

})

157

158

# Set tags for categorization

159

client.tags_context({

160

'environment': 'production',

161

'version': '1.2.3',

162

'feature_flag': 'new_checkout',

163

'user_type': 'premium'

164

})

165

166

# Set extra debugging information

167

client.extra_context({

168

'request_id': 'req_abc123',

169

'session_id': 'sess_xyz789',

170

'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',

171

'referrer': 'https://example.com/products'

172

})

173

174

# This exception will include all the context above

175

try:

176

process_checkout()

177

except Exception:

178

client.captureException()

179

```

180

181

### Request-Scoped Context

182

183

```python

184

from flask import Flask, request

185

from raven.contrib.flask import Sentry

186

187

app = Flask(__name__)

188

sentry = Sentry(app)

189

190

@app.before_request

191

def set_request_context():

192

# Set context for each request

193

sentry.client.user_context({

194

'ip_address': request.remote_addr

195

})

196

197

sentry.client.tags_context({

198

'endpoint': request.endpoint,

199

'method': request.method

200

})

201

202

sentry.client.http_context({

203

'url': request.url,

204

'method': request.method,

205

'headers': dict(request.headers),

206

'query_string': request.query_string.decode()

207

})

208

209

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

210

def get_user(user_id):

211

# Add user-specific context

212

sentry.client.user_context({'id': user_id})

213

sentry.client.tags_context({'operation': 'get_user'})

214

215

try:

216

user = User.get(user_id)

217

return jsonify(user.to_dict())

218

except UserNotFound:

219

# This will include all the request context

220

sentry.captureException()

221

return jsonify({'error': 'User not found'}), 404

222

```

223

224

### Manual Context Management

225

226

```python

227

from raven.context import Context

228

229

def process_user_request(user_id, request_data):

230

context = Context()

231

232

# Activate context for this operation

233

context.activate()

234

235

try:

236

# Merge user-specific data

237

context.merge({

238

'user': {'id': user_id},

239

'tags': {'operation': 'user_request'},

240

'extra': {'request_size': len(str(request_data))}

241

})

242

243

# Process request - any errors will include context

244

result = complex_operation(request_data)

245

246

return result

247

248

finally:

249

# Clean up context

250

context.deactivate()

251

```

252

253

### Context Inheritance in Threads

254

255

```python

256

import threading

257

from raven import Client

258

from raven.context import Context

259

260

client = Client('https://your-dsn@sentry.io/project-id')

261

262

def worker_thread(task_id, user_id):

263

# Create context for this thread

264

context = Context()

265

context.activate()

266

267

# Set thread-specific context

268

context.merge({

269

'user': {'id': user_id},

270

'tags': {

271

'task_id': task_id,

272

'thread': threading.current_thread().name

273

},

274

'extra': {'start_time': time.time()}

275

})

276

277

try:

278

# This work will have the thread context

279

result = process_task(task_id)

280

client.captureMessage(f'Task {task_id} completed successfully')

281

return result

282

283

except Exception:

284

# Exception will include thread context

285

client.captureException()

286

raise

287

finally:

288

context.deactivate()

289

290

# Main thread context

291

client.user_context({'id': 'system'})

292

client.tags_context({'component': 'task_manager'})

293

294

# Spawn worker threads

295

threads = []

296

for i in range(5):

297

t = threading.Thread(

298

target=worker_thread,

299

args=(f'task_{i}', f'user_{i}')

300

)

301

threads.append(t)

302

t.start()

303

304

for t in threads:

305

t.join()

306

```

307

308

### Context Middleware Pattern

309

310

```python

311

from raven import Client

312

313

class SentryContextMiddleware:

314

def __init__(self, client):

315

self.client = client

316

317

def __call__(self, environ, start_response):

318

# Extract request information

319

request_method = environ.get('REQUEST_METHOD')

320

path_info = environ.get('PATH_INFO')

321

query_string = environ.get('QUERY_STRING')

322

remote_addr = environ.get('REMOTE_ADDR')

323

324

# Set request context

325

self.client.http_context({

326

'url': f"{path_info}?{query_string}" if query_string else path_info,

327

'method': request_method,

328

'headers': self._get_headers(environ),

329

'query_string': query_string,

330

})

331

332

self.client.tags_context({

333

'path': path_info,

334

'method': request_method

335

})

336

337

self.client.extra_context({

338

'remote_addr': remote_addr,

339

'server_name': environ.get('SERVER_NAME'),

340

'server_port': environ.get('SERVER_PORT')

341

})

342

343

try:

344

return self.app(environ, start_response)

345

except Exception:

346

self.client.captureException()

347

raise

348

349

def _get_headers(self, environ):

350

headers = {}

351

for key, value in environ.items():

352

if key.startswith('HTTP_'):

353

header_name = key[5:].replace('_', '-').title()

354

headers[header_name] = value

355

return headers

356

357

# Use with WSGI app

358

app = get_wsgi_app()

359

client = Client('https://your-dsn@sentry.io/project-id')

360

app = SentryContextMiddleware(client)(app)

361

```

362

363

### Dynamic Context Updates

364

365

```python

366

from raven import Client

367

368

class ContextualClient:

369

def __init__(self, dsn):

370

self.client = Client(dsn)

371

self._context_stack = []

372

373

def push_context(self, **context_data):

374

"""Push new context data onto stack."""

375

self._context_stack.append(context_data)

376

self._update_client_context()

377

378

def pop_context(self):

379

"""Pop most recent context data from stack."""

380

if self._context_stack:

381

self._context_stack.pop()

382

self._update_client_context()

383

384

def _update_client_context(self):

385

"""Update client with merged context from stack."""

386

merged_context = {}

387

for context in self._context_stack:

388

for key, value in context.items():

389

if key in merged_context and isinstance(value, dict):

390

merged_context[key].update(value)

391

else:

392

merged_context[key] = value

393

394

# Apply to client

395

if 'user' in merged_context:

396

self.client.user_context(merged_context['user'])

397

if 'tags' in merged_context:

398

self.client.tags_context(merged_context['tags'])

399

if 'extra' in merged_context:

400

self.client.extra_context(merged_context['extra'])

401

402

def capture_exception(self, **kwargs):

403

return self.client.captureException(**kwargs)

404

405

def capture_message(self, message, **kwargs):

406

return self.client.captureMessage(message, **kwargs)

407

408

# Usage

409

contextual_client = ContextualClient('https://your-dsn@sentry.io/project-id')

410

411

# Set base context

412

contextual_client.push_context(

413

user={'id': 123},

414

tags={'component': 'auth'}

415

)

416

417

# Add operation-specific context

418

contextual_client.push_context(

419

tags={'operation': 'login'},

420

extra={'login_method': 'password'}

421

)

422

423

try:

424

authenticate_user()

425

except AuthError:

426

# Captures with merged context

427

contextual_client.capture_exception()

428

429

# Remove operation context, keep base context

430

contextual_client.pop_context()

431

```

432

433

### Context-Aware Decorators

434

435

```python

436

from functools import wraps

437

from raven import Client

438

439

client = Client('https://your-dsn@sentry.io/project-id')

440

441

def with_context(**context_data):

442

"""Decorator to add context to function execution."""

443

def decorator(func):

444

@wraps(func)

445

def wrapper(*args, **kwargs):

446

# Store original context

447

original_user = getattr(client.context, 'user', {})

448

original_tags = getattr(client.context, 'tags', {})

449

original_extra = getattr(client.context, 'extra', {})

450

451

try:

452

# Apply decorator context

453

if 'user' in context_data:

454

client.user_context(context_data['user'])

455

if 'tags' in context_data:

456

client.tags_context(context_data['tags'])

457

if 'extra' in context_data:

458

client.extra_context(context_data['extra'])

459

460

return func(*args, **kwargs)

461

462

except Exception:

463

client.captureException()

464

raise

465

finally:

466

# Restore original context

467

client.user_context(original_user)

468

client.tags_context(original_tags)

469

client.extra_context(original_extra)

470

471

return wrapper

472

return decorator

473

474

@with_context(

475

tags={'operation': 'payment'},

476

extra={'processor': 'stripe'}

477

)

478

def process_payment(amount, user_id):

479

# Add function-specific context

480

client.user_context({'id': user_id})

481

client.extra_context({'amount': amount})

482

483

# Any errors here will include all context

484

return stripe.charge(amount)

485

```