or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations-metadata.mdaws-services.mdconfiguration-plugins.mdcore-recording.mddatabase-integration.mdhttp-utilities.mdindex.mdlibrary-patching.mdsampling.mdweb-frameworks.md

annotations-metadata.mddocs/

0

# Annotations and Metadata

1

2

Data attachment capabilities for enriching X-Ray traces with searchable annotations and debugging metadata. Annotations are indexed and searchable in the X-Ray console, while metadata provides additional context for debugging and analysis.

3

4

## Capabilities

5

6

### Annotation Management

7

8

Add searchable key-value pairs to traces that are indexed by X-Ray for filtering and analysis.

9

10

```python { .api }

11

def put_annotation(key: str, value: str) -> None:

12

"""

13

Add an annotation to the current active trace entity.

14

15

Args:

16

key (str): Annotation key (must be a string)

17

value (str): Annotation value (must be a string)

18

19

Notes:

20

- Annotations are indexed and searchable in X-Ray console

21

- Maximum 50 annotations per segment/subsegment

22

- Key and value must be strings

23

- Used for filtering traces in X-Ray console queries

24

"""

25

```

26

27

### Metadata Management

28

29

Add arbitrary structured data to traces for debugging and context information.

30

31

```python { .api }

32

def put_metadata(key: str, value: Any, namespace: str = 'default') -> None:

33

"""

34

Add metadata to the current active trace entity.

35

36

Args:

37

key (str): Metadata key

38

value (Any): Metadata value (can be any JSON-serializable type)

39

namespace (str): Optional namespace for organizing metadata (default: 'default')

40

41

Notes:

42

- Metadata is not indexed but provides rich debugging context

43

- Can store complex objects, lists, dictionaries

44

- Organized by namespaces for better organization

45

- No limit on metadata size (within segment size limits)

46

"""

47

```

48

49

### Sampling Status

50

51

Check if the current trace is being sampled to optimize expensive operations.

52

53

```python { .api }

54

def is_sampled() -> bool:

55

"""

56

Check if the current trace entity is being sampled.

57

58

Returns:

59

bool: True if the current entity is sampled, False otherwise

60

61

Notes:

62

- Use to conditionally execute expensive annotation/metadata generation

63

- Unsampled traces still record structure but skip detailed data

64

"""

65

```

66

67

## Entity-Level Methods

68

69

### Segment and Subsegment Methods

70

71

Both Segment and Subsegment classes provide direct methods for adding annotations and metadata.

72

73

```python { .api }

74

class Segment:

75

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

76

"""Add annotation directly to this segment."""

77

78

def put_metadata(self, key: str, value: Any, namespace: str = 'default') -> None:

79

"""Add metadata directly to this segment."""

80

81

class Subsegment:

82

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

83

"""Add annotation directly to this subsegment."""

84

85

def put_metadata(self, key: str, value: Any, namespace: str = 'default') -> None:

86

"""Add metadata directly to this subsegment."""

87

```

88

89

### HTTP-Specific Metadata

90

91

Add HTTP-related metadata to traces for web applications.

92

93

```python { .api }

94

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

95

"""

96

Add HTTP-specific metadata to the current trace entity.

97

98

Args:

99

key (str): HTTP metadata key ('url', 'method', 'status', 'user_agent', etc.)

100

value (Any): HTTP metadata value

101

102

Common Keys:

103

- 'url': Request URL

104

- 'method': HTTP method (GET, POST, etc.)

105

- 'status': HTTP status code

106

- 'user_agent': Client user agent

107

- 'client_ip': Client IP address

108

- 'content_length': Response content length

109

"""

110

```

111

112

### Status Flags

113

114

Mark traces with status indicators for error analysis.

115

116

```python { .api }

117

def add_throttle_flag() -> None:

118

"""Mark the current entity as throttled."""

119

120

def add_fault_flag() -> None:

121

"""Mark the current entity as having a fault (5xx errors)."""

122

123

def add_error_flag() -> None:

124

"""Mark the current entity as having an error (4xx errors)."""

125

126

def apply_status_code(status_code: int) -> None:

127

"""

128

Apply HTTP status code effects to the current entity.

129

130

Args:

131

status_code (int): HTTP status code

132

133

Effects:

134

- 4xx codes: Adds error flag

135

- 5xx codes: Adds fault flag

136

- 429 code: Adds throttle flag

137

"""

138

```

139

140

### Exception Handling

141

142

Automatically capture exception information in traces.

143

144

```python { .api }

145

def add_exception(exception: Exception, stack: list = None, remote: bool = False) -> None:

146

"""

147

Add exception information to the current trace entity.

148

149

Args:

150

exception (Exception): Exception object to record

151

stack (list): Optional stack trace (auto-generated if not provided)

152

remote (bool): Whether the exception originated from a remote service

153

154

Notes:

155

- Automatically called when exceptions occur within traced code

156

- Can be called manually for custom exception handling

157

- Records exception type, message, and stack trace

158

"""

159

```

160

161

## Usage Patterns

162

163

### Basic Annotations

164

165

```python

166

from aws_xray_sdk.core import xray_recorder

167

168

with xray_recorder.in_segment('user-request') as segment:

169

# Add searchable annotations

170

xray_recorder.put_annotation('user_id', '12345')

171

xray_recorder.put_annotation('user_type', 'premium')

172

xray_recorder.put_annotation('region', 'us-east-1')

173

174

# These annotations can be used for filtering in X-Ray console:

175

# annotation.user_type = "premium"

176

# annotation.region = "us-east-1"

177

```

178

179

### Rich Metadata

180

181

```python

182

from aws_xray_sdk.core import xray_recorder

183

184

with xray_recorder.in_segment('api-request') as segment:

185

# Add structured metadata

186

xray_recorder.put_metadata('request_info', {

187

'method': 'POST',

188

'path': '/api/users',

189

'query_params': {'limit': 50, 'offset': 0},

190

'headers': {'user-agent': 'MyApp/1.0'},

191

'payload_size': 1024

192

})

193

194

# Add metadata in different namespaces

195

xray_recorder.put_metadata('database_config', {

196

'host': 'db.example.com',

197

'database': 'users',

198

'connection_pool_size': 10

199

}, namespace='database')

200

201

xray_recorder.put_metadata('feature_flags', {

202

'new_ui': True,

203

'advanced_search': False,

204

'beta_features': True

205

}, namespace='configuration')

206

```

207

208

### Conditional Expensive Operations

209

210

```python

211

from aws_xray_sdk.core import xray_recorder

212

213

with xray_recorder.in_segment('data-processing') as segment:

214

# Only perform expensive operations if trace is sampled

215

if xray_recorder.is_sampled():

216

# Generate expensive debugging information

217

performance_metrics = analyze_performance_deep()

218

system_state = capture_system_state()

219

220

xray_recorder.put_metadata('performance', performance_metrics)

221

xray_recorder.put_metadata('system_state', system_state)

222

223

# Generate detailed annotations

224

xray_recorder.put_annotation('cpu_usage', str(performance_metrics['cpu']))

225

xray_recorder.put_annotation('memory_usage', str(performance_metrics['memory']))

226

else:

227

# Minimal annotation for unsampled traces

228

xray_recorder.put_annotation('operation', 'data_processing')

229

```

230

231

### HTTP Request Tracing

232

233

```python

234

from aws_xray_sdk.core import xray_recorder

235

import requests

236

237

with xray_recorder.in_segment('web-request') as segment:

238

# Add HTTP-specific metadata

239

segment.put_http_meta('method', 'GET')

240

segment.put_http_meta('url', 'https://api.example.com/users')

241

segment.put_http_meta('user_agent', 'MyApp/1.0')

242

243

try:

244

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

245

246

# Add response information

247

segment.put_http_meta('status', response.status_code)

248

segment.put_http_meta('content_length', len(response.content))

249

250

# Apply status code effects

251

segment.apply_status_code(response.status_code)

252

253

# Add business logic annotations

254

xray_recorder.put_annotation('api_version', response.headers.get('API-Version', 'unknown'))

255

xray_recorder.put_annotation('response_size', str(len(response.content)))

256

257

except requests.RequestException as e:

258

# Exception is automatically captured

259

xray_recorder.put_annotation('error_type', 'network_error')

260

raise

261

```

262

263

### Database Operation Tracing

264

265

```python

266

from aws_xray_sdk.core import xray_recorder

267

import sqlite3

268

269

with xray_recorder.in_segment('database-operation') as segment:

270

with xray_recorder.in_subsegment('user-query') as subsegment:

271

# Add database-specific annotations

272

subsegment.put_annotation('table', 'users')

273

subsegment.put_annotation('operation', 'SELECT')

274

subsegment.put_annotation('index_used', 'user_id_idx')

275

276

# Add detailed metadata

277

subsegment.put_metadata('query_info', {

278

'sql': 'SELECT * FROM users WHERE user_id = ?',

279

'parameters': ['12345'],

280

'estimated_rows': 1,

281

'execution_plan': 'index_scan'

282

}, namespace='database')

283

284

# Execute query

285

conn = sqlite3.connect('app.db')

286

cursor = conn.cursor()

287

cursor.execute('SELECT * FROM users WHERE user_id = ?', ('12345',))

288

result = cursor.fetchone()

289

290

# Add result metadata

291

subsegment.put_metadata('result_info', {

292

'rows_returned': 1 if result else 0,

293

'execution_time_ms': 15.2,

294

'cache_hit': False

295

}, namespace='database')

296

```

297

298

### Error Handling and Status

299

300

```python

301

from aws_xray_sdk.core import xray_recorder

302

303

with xray_recorder.in_segment('error-prone-operation') as segment:

304

try:

305

# Risky operation

306

result = perform_risky_operation()

307

308

# Success annotations

309

xray_recorder.put_annotation('status', 'success')

310

311

except ValueError as e:

312

# Client error (4xx equivalent)

313

segment.add_error_flag()

314

xray_recorder.put_annotation('error_type', 'validation_error')

315

xray_recorder.put_metadata('error_details', {

316

'error_message': str(e),

317

'error_code': 'INVALID_INPUT'

318

})

319

raise

320

321

except ConnectionError as e:

322

# Server fault (5xx equivalent)

323

segment.add_fault_flag()

324

xray_recorder.put_annotation('error_type', 'connection_error')

325

raise

326

327

except Exception as e:

328

# Unknown error

329

segment.add_fault_flag()

330

xray_recorder.put_annotation('error_type', 'unknown_error')

331

# Exception details are automatically captured

332

raise

333

```

334

335

### Entity-Specific Metadata

336

337

```python

338

from aws_xray_sdk.core import xray_recorder

339

340

with xray_recorder.in_segment('multi-step-process') as segment:

341

# Segment-level metadata

342

segment.put_annotation('process_type', 'batch_job')

343

segment.put_metadata('job_config', {

344

'batch_size': 1000,

345

'timeout': 300,

346

'retry_count': 3

347

})

348

349

for i in range(3):

350

with xray_recorder.in_subsegment(f'step-{i+1}') as subsegment:

351

# Subsegment-specific metadata

352

subsegment.put_annotation('step_number', str(i+1))

353

subsegment.put_metadata('step_config', {

354

'input_size': 100 * (i+1),

355

'processing_mode': 'parallel' if i > 0 else 'sequential'

356

})

357

358

# Process step

359

process_step(i+1)

360

```

361

362

## Best Practices

363

364

### Annotation Guidelines

365

366

1. **Use for Filtering**: Only add annotations that you'll use for filtering in X-Ray console

367

2. **String Values Only**: Annotations must have string keys and string values

368

3. **Limit Quantity**: Maximum 50 annotations per segment/subsegment

369

4. **Meaningful Names**: Use descriptive keys like 'user_id', 'operation_type', 'region'

370

371

### Metadata Guidelines

372

373

1. **Rich Context**: Use metadata for detailed debugging information

374

2. **Namespace Organization**: Group related metadata using namespaces

375

3. **JSON Serializable**: Ensure metadata values can be serialized to JSON

376

4. **Size Consideration**: Large metadata affects segment size and performance

377

378

### Performance Optimization

379

380

```python

381

from aws_xray_sdk.core import xray_recorder

382

383

with xray_recorder.in_segment('optimized-operation') as segment:

384

# Always add essential annotations

385

xray_recorder.put_annotation('operation_id', operation_id)

386

387

# Conditionally add expensive metadata

388

if xray_recorder.is_sampled():

389

# Expensive operations only for sampled traces

390

detailed_metrics = generate_detailed_metrics()

391

xray_recorder.put_metadata('detailed_metrics', detailed_metrics)

392

393

# Lightweight annotations for all traces

394

xray_recorder.put_annotation('status', 'processed')

395

```