Context Management
Relevant source files
The following files were used as context for generating this wiki page:
Context Management within the FLEXT Observability ecosystem provides a robust mechanism for rich metadata propagation, request-local storage, and distributed tracing correlation. Its primary purpose is to ensure that observability data—such as metrics, traces, and logs—carries consistent correlation identifiers and domain-specific metadata across asynchronous operations and service boundaries.
The system is built on Clean Architecture principles, separating the domain entities (models) from the application services that manage request-local state. By utilizing specialized components like the FlextObservabilityAdvancedContext, the project supports W3C Baggage API integration and metadata snapshots, which are critical for debugging and distributed tracing in complex environments.
Sources: src/flext_observability/services/advanced_context.py:1-25, src/flext_observability/README.md:10-25
Advanced Context Architecture
The context management system relies on a request-local storage pattern that is separate from standard asynchronous contexts. This allows for fine-grained control over metadata such as User IDs, Tenant IDs, and Request IDs.
Key Components
| Component | Description |
|---|---|
FlextObservabilityAdvancedContext | The primary service providing the API for metadata and baggage management. |
Context | A nested class within the service that manages actual storage for metadata and baggage. |
ContextSnapshot | A Pydantic model used to capture the state of a context for restoration in async callbacks or background tasks. |
LogContext | A model for enriching log entries with trace, span, and correlation IDs. |
Sources: src/flext_observability/services/advanced_context.py:31-50, src/flext_observability/models.py:126-150
The following diagram illustrates the relationship between the Advanced Context service and its underlying data models:
Metadata and Baggage Propagation
Context Management distinguishes between "Metadata" (internal request-local data) and "Baggage" (propagated key-value pairs following W3C standards).
Metadata Management
Metadata is used to store request-specific information that stays within the service boundary but is essential for observability. Common examples include tenant_id and user_id.
- Validation: Metadata values must be JSON serializable.
- Storage: Handled in
_metadatamapping within the request-local context.
Baggage API
Baggage allows for the propagation of data across service boundaries. It is primarily managed through the update_baggage and resolve_baggage methods.
Sources: src/flext_observability/services/advanced_context.py:100-140, tests/integration/test_phase_11_integration.py:115-125
Context Flow for Async Operations
When transitioning between threads or async tasks, the context can be "snapshotted" and "restored" to maintain continuity.
Data Models for Context
The domain models defined in models.py provide the structure for context-related entities. These models use Pydantic for validation and serialization.
ContextSnapshot Fields
| Field | Type | Description |
|---|---|---|
correlation_id | str | Unique identifier for the transaction flow. |
trace_id | str | Distributed tracing identifier. |
span_id | str | Current operation identifier. |
baggage | StrMapping | Propagated key-value pairs. |
metadata | ConfigurationMapping | Additional context metadata. |
Sources: src/flext_observability/models.py:126-140
Log Enrichment
Context management extends to logging via the LogContext model, which ensures that every structured log entry contains the necessary identifiers for correlation.
# Example of LogContext structure from models.py
class LogContext(m.Value):
correlation_id: str | None = None
trace_id: str | None = None
span_id: str | None = None
extra: m.Dict = m.Dict({})
Sources: src/flext_observability/models.py:220-235
Usage Patterns
Integration tests and examples demonstrate the lifecycle of context management, from initialization to metadata resolution.
- Initialization: Accessing the singleton instance via
active_context(). - Updates: Adding metadata or baggage during a request's lifecycle.
- Snapshotting: Capturing state before an asynchronous jump.
- Verification: Using
resolve_metadatato ensure propagation.
# Based on integration test patterns
ctx = FlextObservabilityAdvancedContext.active_context()
ctx.update_metadata("user_id", "user-123")
ctx.update_baggage("org_id", "org-456")
# Snapshot for async transfer
snapshot = ctx.snapshot(correlation_id="async-001")
# Clean and Restore
ctx.clear()
ctx.restore(snapshot)
assert ctx.resolve_metadata("user_id") == "user-123"
Sources: tests/integration/test_phase_11_integration.py:115-135, src/flext_observability/services/advanced_context.py:150-185
Conclusion
Context Management is a cornerstone of the FLEXT Observability platform, providing the glue that binds disparate metrics, traces, and logs into a coherent narrative. Through the use of FlextObservabilityAdvancedContext and the ContextSnapshot mechanism, developers can ensure that critical metadata is preserved across complex, asynchronous execution paths, enabling deep visibility into enterprise-scale systems.
Sources: src/flext_observability/README.md:30-45, examples/README.md:140-155