-
Notifications
You must be signed in to change notification settings - Fork 0
Home
The modern context propagation, structured logging, and distributed tracing bridge for Java 21+, Spring Boot, and Virtual Threads (Project Loom).
Modern Java applications increasingly rely on asynchronous execution, reactive streams, and lightweight virtual threads (Project Loom).
However, traditional context propagation mechanisms like ThreadLocal and SLF4J's MDC fail as soon as an asynchronous task or thread boundary is crossed:
// Traditional MDC issue:
MDC.put("order.id", "ORD-9988");
executor.submit(() -> {
// 💥 Context lost! MDC.get("order.id") returns null!
log.info("Processing order");
});ScopeFlow completely eliminates this problem. It acts as a unified context broker that automatically propagates technical and business metadata across:
- 🧵 Platform & Virtual Threads (Executors, CompletableFutures, ForkJoinPool)
- 📝 SLF4J MDC Logging (correlated logs in Logback/Log4j2 with automatic cleanups)
- 🔭 OpenTelemetry Baggage (propagates across microservices via distributed tracing headers)
- 📊 Micrometer Context Propagation (Project Reactor & WebFlux reactive chains)
- ⚡ Java 23+ ScopedValue & StructuredTaskScope (structured concurrency support)
flowchart TD
subgraph Client["Incoming Request"]
HTTP["HTTP / REST / gRPC Request"]
end
subgraph ScopeFlow["ScopeFlow Context Manager"]
SF["ScopeFlow.open('scope.name', contextMap)"]
CTX[("Immutable ScopeContext")]
SF --> CTX
end
subgraph Propagators["Active Bridges & Propagators"]
MDC["SLF4J MDC Propagator<br/>(Logs & Correlation ID)"]
OTEL["OpenTelemetry Propagator<br/>(Trace Baggage)"]
MICRO["Micrometer Propagator<br/>(Reactor & Metrics)"]
SCOPED["ScopedValue Propagator<br/>(Java 21/23 Loom)"]
end
subgraph Execution["Async & Cross-Thread Boundaries"]
VT["Virtual Threads (Loom)"]
EX["ThreadPoolTaskExecutor / Async"]
CF["CompletableFuture / ForkJoinPool"]
end
HTTP --> SF
CTX --> MDC
CTX --> OTEL
CTX --> MICRO
CTX --> SCOPED
MDC & OTEL & MICRO & SCOPED -->|Automatic Context Restore| Execution
Use the navigation sidebar on the right or explore the chapters below:
Everything you need to install ScopeFlow via Maven Central or Gradle, configure your first scope, and integrate it in under 5 minutes.
Deep dive into the architectural design: Scope, ScopeContext, Propagator, snapshots, nesting scopes, and deterministic resource lifecycle.
Learn about the scopeflow-spring-boot-starter: auto-configuration, ScopeFlowWebMvcInterceptor, automatic request ID generation, and @Async integration.
Explore wrappers (wrap(Runnable), wrap(Callable)), decorator executors (ScopeFlowTaskDecorator), and seamless virtual thread handoffs.
How ScopeFlow handles SLF4J MDC without memory leaks: push/pop stack handling, MDC key policies (allow/deny lists, prefix filters), and Logback configuration.
Propagate business context into OpenTelemetry Baggage and correlate traces across microservices automatically.
Bridge Spring Boot 3's Micrometer Context Propagation to support Project Reactor, WebFlux, and reactive pipelines.
Modern Java 21/23 preview features: benchmarked ScopedValue performance and concurrent branching with StructuredTaskScope.ShutdownOnFailure.
Comprehensive reference table of all application.yml properties, defaults, and programmatic ScopeFlowBuilder options.
Essential recommendations, production tips, security considerations, and common pitfalls to avoid.
Add the starter to your Spring Boot project (Java 21+):
<dependency>
<groupId>io.github.frodygr</groupId>
<artifactId>scopeflow-spring-boot-starter</artifactId>
<version>1.0.2</version>
</dependency>Or for standalone (no Spring) projects:
<dependency>
<groupId>io.github.frodygr</groupId>
<artifactId>scopeflow-core</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>io.github.frodygr</groupId>
<artifactId>scopeflow-mdc</artifactId>
<version>1.0.2</version>
</dependency>@RestController
public class PaymentController {
@Autowired
private ScopeFlow scopeFlow;
@PostMapping("/checkout")
public PaymentResponse checkout(@RequestBody CheckoutRequest request) {
// Automatically injects customer & transaction metadata into current thread, logs, and telemetry
try (Scope scope = scopeFlow.open("payment.process", Map.of(
"customer.id", request.customerId(),
"order.amount", request.amount()
))) {
log.info("Processing checkout");
// Logback: [req=4f92] [customer.id=CUST-10] [order.amount=99.50] Processing checkout
// Context safely propagates to background virtual threads:
Thread.startVirtualThread(scopeFlow.wrap(() -> {
log.info("Auditing transaction asynchronously");
// Context is still preserved!
}));
return paymentService.process(request);
} // Exiting the try-with-resources safely restores previous context!
}
}Have questions or need help? Check out our Best Practices or visit the GitHub Repository.
ScopeFlow • Distributed Context & Tracing Propagation • Licensed under Apache-2.0