0
# Configuration and Plugins
1
2
Recorder configuration options, plugin system for AWS metadata collection, and global SDK settings. Includes sampling configuration, context management, environment-specific plugins, and comprehensive customization options.
3
4
## Capabilities
5
6
### Recorder Configuration
7
8
Configure the X-Ray recorder with comprehensive settings for sampling, plugins, error handling, and performance optimization.
9
10
```python { .api }
11
def configure(
12
sampling: bool = None,
13
plugins: tuple = None,
14
context_missing: str = None,
15
sampling_rules: str = None,
16
daemon_address: str = None,
17
service: str = None,
18
context: object = None,
19
emitter: object = None,
20
streaming: bool = None,
21
dynamic_naming: str = None,
22
streaming_threshold: int = None,
23
max_trace_back: int = None,
24
sampler: object = None,
25
stream_sql: bool = None
26
) -> None:
27
"""
28
Configure the X-Ray recorder with various settings.
29
30
Args:
31
sampling (bool): Enable/disable sampling (default: True)
32
plugins (tuple): Plugin names to load ('EC2Plugin', 'ECSPlugin', 'ElasticBeanstalkPlugin')
33
context_missing (str): Behavior when no active segment ('LOG_ERROR', 'RUNTIME_ERROR', 'IGNORE_ERROR')
34
sampling_rules (str): Path to JSON file containing sampling rules
35
daemon_address (str): X-Ray daemon address in format 'host:port' (default: '127.0.0.1:2000')
36
service (str): Service name override for dynamic segment naming
37
context (object): Context implementation for trace entity storage
38
emitter (object): Custom emitter for sending traces to daemon
39
streaming (bool): Enable subsegment streaming for large traces
40
dynamic_naming (str): Pattern for dynamic segment naming (e.g., '*.example.com*')
41
streaming_threshold (int): Number of subsegments before streaming (default: 20)
42
max_trace_back (int): Maximum stack trace depth for exceptions (default: 10)
43
sampler (object): Custom sampler implementation
44
stream_sql (bool): Enable SQL query streaming for database traces
45
"""
46
```
47
48
### Global SDK Configuration
49
50
Global SDK settings that control overall X-Ray functionality across the application.
51
52
```python { .api }
53
class SDKConfig:
54
"""Global SDK configuration management."""
55
56
@classmethod
57
def sdk_enabled(cls) -> bool:
58
"""
59
Check if the X-Ray SDK is globally enabled.
60
61
Returns:
62
bool: True if SDK is enabled, False otherwise
63
64
Notes:
65
- Controlled by AWS_XRAY_SDK_ENABLED environment variable
66
- When disabled, all X-Ray operations become no-ops
67
- AWS_XRAY_NOOP_ID controls trace ID generation (default: True for no-op IDs in unsampled requests)
68
"""
69
70
@classmethod
71
def set_sdk_enabled(cls, value: bool) -> None:
72
"""
73
Enable or disable the X-Ray SDK globally.
74
75
Args:
76
value (bool): True to enable, False to disable
77
78
Notes:
79
- Environment variables take precedence over programmatic settings
80
- Useful for testing and development environments
81
"""
82
```
83
84
### Plugin System
85
86
AWS environment plugins that automatically collect metadata about the runtime environment.
87
88
#### Available Plugins
89
90
```python { .api }
91
class EC2Plugin:
92
"""
93
AWS EC2 metadata plugin.
94
95
Collects:
96
- Instance ID
97
- Availability Zone
98
- Instance Type
99
- AMI ID
100
- Security Groups
101
"""
102
103
class ECSPlugin:
104
"""
105
AWS ECS metadata plugin.
106
107
Collects:
108
- Container ID
109
- Container Name
110
- Task ARN
111
- Task Definition
112
- Cluster Name
113
"""
114
115
class ElasticBeanstalkPlugin:
116
"""
117
AWS Elastic Beanstalk metadata plugin.
118
119
Collects:
120
- Environment Name
121
- Version Label
122
- Deployment ID
123
"""
124
```
125
126
## Configuration Patterns
127
128
### Basic Configuration
129
130
```python
131
from aws_xray_sdk.core import xray_recorder
132
133
# Simple configuration for development
134
xray_recorder.configure(
135
sampling=False, # Disable sampling for dev
136
context_missing='LOG_ERROR', # Log missing context instead of throwing
137
daemon_address='127.0.0.1:2000' # Local daemon address
138
)
139
```
140
141
### Production Configuration
142
143
```python
144
from aws_xray_sdk.core import xray_recorder
145
146
# Production configuration with sampling and plugins
147
xray_recorder.configure(
148
sampling=True, # Enable sampling
149
plugins=('EC2Plugin', 'ECSPlugin'), # Load environment plugins
150
context_missing='LOG_ERROR', # Handle missing context gracefully
151
daemon_address='xray-daemon:2000', # Daemon service address
152
service='production-api', # Service name
153
streaming=True, # Enable streaming for large traces
154
streaming_threshold=50, # Stream after 50 subsegments
155
max_trace_back=20, # Capture more stack trace
156
stream_sql=True # Enable SQL streaming
157
)
158
```
159
160
### Sampling Configuration
161
162
#### Built-in Sampling
163
164
```python
165
from aws_xray_sdk.core import xray_recorder
166
167
# Enable sampling with default rules
168
xray_recorder.configure(sampling=True)
169
170
# Disable sampling (trace everything)
171
xray_recorder.configure(sampling=False)
172
```
173
174
#### Custom Sampling Rules
175
176
```python
177
from aws_xray_sdk.core import xray_recorder
178
179
# Load sampling rules from file
180
xray_recorder.configure(
181
sampling=True,
182
sampling_rules='/path/to/sampling-rules.json'
183
)
184
```
185
186
Example sampling rules file:
187
```json
188
{
189
"version": 2,
190
"default": {
191
"fixed_target": 1,
192
"rate": 0.1
193
},
194
"rules": [
195
{
196
"description": "High priority endpoints",
197
"service_name": "my-service",
198
"http_method": "*",
199
"url_path": "/api/critical/*",
200
"fixed_target": 2,
201
"rate": 1.0
202
},
203
{
204
"description": "Health checks",
205
"service_name": "*",
206
"http_method": "GET",
207
"url_path": "/health",
208
"fixed_target": 0,
209
"rate": 0.01
210
},
211
{
212
"description": "Database operations",
213
"service_name": "database-service",
214
"http_method": "*",
215
"url_path": "*",
216
"fixed_target": 1,
217
"rate": 0.5
218
}
219
]
220
}
221
```
222
223
### Dynamic Naming
224
225
Configure dynamic segment naming based on request characteristics.
226
227
```python
228
from aws_xray_sdk.core import xray_recorder
229
230
# Dynamic naming based on hostname
231
xray_recorder.configure(
232
service='my-service',
233
dynamic_naming='*.example.com*' # Matches any subdomain of example.com
234
)
235
236
# Multiple patterns
237
xray_recorder.configure(
238
service='multi-domain-service',
239
dynamic_naming='*.example.com*,*.test.com*,localhost'
240
)
241
```
242
243
### Context Management
244
245
#### Default Context
246
247
```python
248
from aws_xray_sdk.core import xray_recorder
249
250
# Default context for synchronous applications
251
xray_recorder.configure() # Uses default context
252
```
253
254
#### Async Context
255
256
```python
257
from aws_xray_sdk.core import xray_recorder
258
from aws_xray_sdk.core.async_context import AsyncContext
259
260
# Async context for asynchronous applications
261
xray_recorder.configure(
262
context=AsyncContext()
263
)
264
```
265
266
#### Custom Context
267
268
```python
269
from aws_xray_sdk.core import xray_recorder
270
from aws_xray_sdk.core.context import Context
271
272
class CustomContext(Context):
273
"""Custom context implementation for special requirements."""
274
275
def __init__(self):
276
super().__init__()
277
self.custom_storage = {}
278
279
def put_segment(self, segment):
280
# Custom segment storage logic
281
self.custom_storage[threading.current_thread().ident] = segment
282
283
def get_trace_entity(self):
284
# Custom trace entity retrieval
285
return self.custom_storage.get(threading.current_thread().ident)
286
287
# Use custom context
288
xray_recorder.configure(context=CustomContext())
289
```
290
291
### Error Handling Configuration
292
293
```python
294
from aws_xray_sdk.core import xray_recorder
295
296
# Different error handling strategies
297
xray_recorder.configure(context_missing='LOG_ERROR') # Log and continue
298
xray_recorder.configure(context_missing='RUNTIME_ERROR') # Raise exception
299
xray_recorder.configure(context_missing='IGNORE_ERROR') # Silent ignore
300
```
301
302
## Plugin Usage
303
304
### Environment Detection
305
306
Plugins automatically detect the runtime environment and collect relevant metadata.
307
308
```python
309
from aws_xray_sdk.core import xray_recorder
310
311
# Load all available plugins
312
xray_recorder.configure(
313
plugins=('EC2Plugin', 'ECSPlugin', 'ElasticBeanstalkPlugin')
314
)
315
316
# Plugins automatically detect environment and collect metadata:
317
# - EC2Plugin: Only activates on EC2 instances
318
# - ECSPlugin: Only activates in ECS containers
319
# - ElasticBeanstalkPlugin: Only activates in Elastic Beanstalk environments
320
```
321
322
### Plugin-Specific Configuration
323
324
#### EC2 Plugin
325
326
```python
327
from aws_xray_sdk.core import xray_recorder
328
329
# EC2 plugin automatically collects:
330
xray_recorder.configure(plugins=('EC2Plugin',))
331
332
# Metadata collected:
333
# {
334
# "ec2": {
335
# "instance_id": "i-1234567890abcdef0",
336
# "availability_zone": "us-west-2a",
337
# "instance_type": "m5.large",
338
# "ami_id": "ami-12345678",
339
# "instance_size": "m5.large"
340
# }
341
# }
342
```
343
344
#### ECS Plugin
345
346
```python
347
from aws_xray_sdk.core import xray_recorder
348
349
# ECS plugin for containerized applications
350
xray_recorder.configure(plugins=('ECSPlugin',))
351
352
# Metadata collected:
353
# {
354
# "ecs": {
355
# "container": "my-app-container",
356
# "container_id": "abcd1234",
357
# "task_arn": "arn:aws:ecs:us-west-2:123456789012:task/my-task",
358
# "task_family": "my-task-family",
359
# "cluster_name": "my-cluster"
360
# }
361
# }
362
```
363
364
#### Elastic Beanstalk Plugin
365
366
```python
367
from aws_xray_sdk.core import xray_recorder
368
369
# Elastic Beanstalk plugin
370
xray_recorder.configure(plugins=('ElasticBeanstalkPlugin',))
371
372
# Metadata collected:
373
# {
374
# "elastic_beanstalk": {
375
# "environment_name": "my-app-prod",
376
# "version_label": "v1.2.3",
377
# "deployment_id": "12345"
378
# }
379
# }
380
```
381
382
### Plugin Verification
383
384
```python
385
from aws_xray_sdk.core import xray_recorder
386
387
# Check which plugins are loaded and active
388
xray_recorder.configure(plugins=('EC2Plugin', 'ECSPlugin'))
389
390
# Plugin metadata is automatically added to segments
391
with xray_recorder.in_segment('plugin-demo') as segment:
392
# Plugin metadata is automatically attached
393
# You can access it programmatically if needed
394
segment_dict = segment.to_dict()
395
aws_metadata = segment_dict.get('aws', {})
396
397
if 'ec2' in aws_metadata:
398
print(f"Running on EC2 instance: {aws_metadata['ec2']['instance_id']}")
399
400
if 'ecs' in aws_metadata:
401
print(f"Running in ECS container: {aws_metadata['ecs']['container']}")
402
```
403
404
## Advanced Configuration
405
406
### Custom Emitter
407
408
```python
409
from aws_xray_sdk.core import xray_recorder
410
from aws_xray_sdk.core.emitters.udp_emitter import UDPEmitter
411
412
class CustomEmitter(UDPEmitter):
413
"""Custom emitter with additional processing."""
414
415
def send_entity(self, entity):
416
# Add custom processing before sending
417
self.preprocess_entity(entity)
418
419
# Call parent implementation
420
super().send_entity(entity)
421
422
def preprocess_entity(self, entity):
423
# Custom preprocessing logic
424
entity_dict = entity.to_dict()
425
426
# Add custom metadata
427
if 'metadata' not in entity_dict:
428
entity_dict['metadata'] = {}
429
430
entity_dict['metadata']['custom'] = {
431
'processed_at': time.time(),
432
'version': '1.0'
433
}
434
435
# Use custom emitter
436
custom_emitter = CustomEmitter()
437
xray_recorder.configure(emitter=custom_emitter)
438
```
439
440
### Custom Sampler
441
442
```python
443
from aws_xray_sdk.core import xray_recorder
444
from aws_xray_sdk.core.sampling.sampler import Sampler
445
446
class CustomSampler(Sampler):
447
"""Custom sampler with business logic."""
448
449
def should_trace(self, sampling_req):
450
# Custom sampling logic based on request
451
service_name = sampling_req.get('service_name', '')
452
url_path = sampling_req.get('url_path', '')
453
454
# Always trace errors
455
if 'error' in url_path.lower():
456
return True
457
458
# Never trace health checks
459
if url_path == '/health':
460
return False
461
462
# Custom rate based on service
463
if service_name == 'critical-service':
464
return random.random() < 0.8 # 80% sampling
465
466
# Default rate
467
return random.random() < 0.1 # 10% sampling
468
469
# Use custom sampler
470
custom_sampler = CustomSampler()
471
xray_recorder.configure(sampler=custom_sampler)
472
```
473
474
### Environment-Based Configuration
475
476
```python
477
import os
478
from aws_xray_sdk.core import xray_recorder
479
480
def configure_xray_for_environment():
481
"""Configure X-Ray based on environment variables."""
482
483
environment = os.getenv('ENVIRONMENT', 'development')
484
debug_mode = os.getenv('DEBUG', 'false').lower() == 'true'
485
486
if environment == 'production':
487
# Production configuration
488
xray_recorder.configure(
489
sampling=True,
490
plugins=('EC2Plugin', 'ECSPlugin'),
491
context_missing='LOG_ERROR',
492
daemon_address=os.getenv('XRAY_DAEMON_ADDRESS', 'xray-daemon:2000'),
493
service=os.getenv('SERVICE_NAME', 'production-service'),
494
streaming=True,
495
streaming_threshold=100,
496
stream_sql=False # Disable SQL streaming in production
497
)
498
499
elif environment == 'staging':
500
# Staging configuration
501
xray_recorder.configure(
502
sampling=True,
503
plugins=('EC2Plugin',),
504
context_missing='LOG_ERROR',
505
daemon_address=os.getenv('XRAY_DAEMON_ADDRESS', '127.0.0.1:2000'),
506
service=f"staging-{os.getenv('SERVICE_NAME', 'service')}",
507
stream_sql=True
508
)
509
510
else:
511
# Development configuration
512
xray_recorder.configure(
513
sampling=not debug_mode, # Disable sampling in debug mode
514
context_missing='LOG_ERROR',
515
daemon_address='127.0.0.1:2000',
516
service=f"dev-{os.getenv('SERVICE_NAME', 'service')}",
517
stream_sql=True
518
)
519
520
# Apply environment-based configuration
521
configure_xray_for_environment()
522
```
523
524
### Framework-Specific Configuration
525
526
#### Django Configuration
527
528
```python
529
# settings.py
530
import os
531
532
XRAY_RECORDER = {
533
'AWS_XRAY_TRACING_NAME': os.getenv('SERVICE_NAME', 'Django App'),
534
'PLUGINS': ('EC2Plugin', 'ECSPlugin'),
535
'DAEMON_ADDRESS': os.getenv('XRAY_DAEMON_ADDRESS', '127.0.0.1:2000'),
536
'CONTEXT_MISSING': 'LOG_ERROR',
537
'SAMPLING': os.getenv('ENVIRONMENT') == 'production',
538
'SAMPLING_RULES': os.getenv('XRAY_SAMPLING_RULES'),
539
'STREAM_SQL': os.getenv('XRAY_STREAM_SQL', 'true').lower() == 'true',
540
'AUTO_INSTRUMENT': True,
541
'PATCH_MODULES': [
542
'boto3',
543
'requests',
544
'sqlalchemy_core',
545
],
546
'IGNORE_MODULE_PATTERNS': [
547
'.*test.*',
548
'.*mock.*',
549
],
550
}
551
```
552
553
#### Flask Configuration Class
554
555
```python
556
import os
557
from aws_xray_sdk.core import xray_recorder
558
559
class XRayConfig:
560
"""X-Ray configuration for Flask applications."""
561
562
@staticmethod
563
def init_app(app):
564
# Environment-based configuration
565
environment = app.config.get('ENVIRONMENT', 'development')
566
567
config = {
568
'context_missing': 'LOG_ERROR',
569
'daemon_address': app.config.get('XRAY_DAEMON_ADDRESS', '127.0.0.1:2000'),
570
'service': app.config.get('SERVICE_NAME', 'flask-app'),
571
}
572
573
if environment == 'production':
574
config.update({
575
'sampling': True,
576
'plugins': ('EC2Plugin', 'ECSPlugin'),
577
'streaming': True,
578
'stream_sql': False
579
})
580
else:
581
config.update({
582
'sampling': False,
583
'stream_sql': True
584
})
585
586
# Apply configuration
587
xray_recorder.configure(**config)
588
589
return xray_recorder
590
591
# Usage in Flask app
592
from flask import Flask
593
from aws_xray_sdk.ext.flask.middleware import XRayMiddleware
594
595
app = Flask(__name__)
596
recorder = XRayConfig.init_app(app)
597
XRayMiddleware(app, recorder)
598
```
599
600
## Global SDK Control
601
602
### Environment Variable Control
603
604
```python
605
import os
606
607
# Control SDK enabled state via environment
608
os.environ['AWS_XRAY_SDK_ENABLED'] = 'false' # Disable SDK
609
os.environ['AWS_XRAY_NOOP_ID'] = 'false' # Generate secure random IDs for all requests
610
611
# Check SDK state
612
from aws_xray_sdk import global_sdk_config
613
614
if global_sdk_config.sdk_enabled():
615
print("X-Ray SDK is enabled")
616
else:
617
print("X-Ray SDK is disabled")
618
```
619
620
### Programmatic Control
621
622
```python
623
from aws_xray_sdk import global_sdk_config
624
625
# Disable SDK programmatically
626
global_sdk_config.set_sdk_enabled(False)
627
628
# Re-enable SDK (must also clear environment variable)
629
import os
630
if 'AWS_XRAY_SDK_ENABLED' in os.environ:
631
del os.environ['AWS_XRAY_SDK_ENABLED']
632
633
global_sdk_config.set_sdk_enabled(True)
634
```
635
636
### Testing Configuration
637
638
```python
639
import pytest
640
from aws_xray_sdk import global_sdk_config
641
642
@pytest.fixture
643
def disable_xray():
644
"""Disable X-Ray for testing."""
645
global_sdk_config.set_sdk_enabled(False)
646
yield
647
global_sdk_config.set_sdk_enabled(True)
648
649
def test_my_function(disable_xray):
650
# X-Ray is disabled during this test
651
result = my_function_that_uses_xray()
652
assert result == expected_value
653
```
654
655
## Best Practices
656
657
### Configuration Order
658
659
```python
660
from aws_xray_sdk.core import xray_recorder, patch_all
661
662
# 1. Configure recorder first
663
xray_recorder.configure(
664
sampling=True,
665
plugins=('EC2Plugin',),
666
context_missing='LOG_ERROR'
667
)
668
669
# 2. Then patch libraries
670
patch_all()
671
672
# 3. Finally import and use libraries
673
import requests
674
import boto3
675
```
676
677
### Performance Optimization
678
679
```python
680
from aws_xray_sdk.core import xray_recorder
681
682
# Optimize for high-throughput applications
683
xray_recorder.configure(
684
sampling=True, # Use sampling to reduce overhead
685
streaming=True, # Stream large traces
686
streaming_threshold=20, # Lower threshold for faster streaming
687
max_trace_back=5, # Reduce stack trace depth
688
stream_sql=False # Disable SQL streaming in production
689
)
690
```
691
692
### Error Handling
693
694
```python
695
from aws_xray_sdk.core import xray_recorder
696
697
# Graceful error handling
698
xray_recorder.configure(context_missing='LOG_ERROR')
699
700
# Verify configuration
701
try:
702
with xray_recorder.in_segment('test-segment'):
703
print("X-Ray is working correctly")
704
except Exception as e:
705
print(f"X-Ray configuration issue: {e}")
706
```