Webflux Tracing Assistant APIs

These APIs provide advanced features to enhance interaction capabilities in Webflux cases.

Choose the right toolkit

The toolkit is split by Reactor generation, because reactor.core.publisher.Signal#getContext() was removed in Reactor 3.5.0 and its replacement, Signal#getContextView(), does not exist before Reactor 3.4.0. No single artifact can serve both.

Artifact Java package Reactor Spring Boot
apm-toolkit-webflux-5.x org.apache.skywalking.apm.toolkit.webflux.v5 3.1.3 -> 3.4 2.x
apm-toolkit-webflux-6.x org.apache.skywalking.apm.toolkit.webflux.v6 3.5 -> 3.8 3.x and 4.x

The two artifacts expose exactly the same API, so only the dependency coordinate and the import change. Add one of them — never both.

For Spring Boot 2.x (Reactor 3.1.3 - 3.4):

   <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-webflux-5.x</artifactId>
      <version>${skywalking.version}</version>
   </dependency>
import org.apache.skywalking.apm.toolkit.webflux.v5.WebFluxSkyWalkingOperators;
import org.apache.skywalking.apm.toolkit.webflux.v5.WebFluxSkyWalkingTraceContext;

For Spring Boot 3.x and 4.x (Reactor 3.5+):

   <dependency>
      <groupId>org.apache.skywalking</groupId>
      <artifactId>apm-toolkit-webflux-6.x</artifactId>
      <version>${skywalking.version}</version>
   </dependency>
import org.apache.skywalking.apm.toolkit.webflux.v6.WebFluxSkyWalkingOperators;
import org.apache.skywalking.apm.toolkit.webflux.v6.WebFluxSkyWalkingTraceContext;

Migrating from apm-toolkit-webflux

Before 9.8.0 there was a single un-versioned apm-toolkit-webflux artifact, in package org.apache.skywalking.apm.toolkit.webflux. It is superseded by apm-toolkit-webflux-5.x, and its continueTracing overloads that read the Reactor Signal context never worked on Reactor 3.5+ (Spring Boot 3.0 and later).

To migrate, change the artifactId and the import: pick -5.x to stay on Spring Boot 2.x, or -6.x if you are on Spring Boot 3.x/4.x. Getting the migration itself wrong is caught at build time — a stale coordinate fails to resolve, and a stale import fails to compile.

Upgrade the agent first, or together with the toolkit. Compatibility is only backward, not forward:

Toolkit Agent Result
old apm-toolkit-webflux (<= 9.7.0) 9.8.0+ works — the agent still matches the un-versioned classes
-5.x / -6.x (9.8.0+) <= 9.7.0 silently untraced — the older agent does not know the .v5 / .v6 classes, so it never instruments them

The second row compiles and runs perfectly normally; the only symptom is that the toolkit calls stop producing spans. So do not roll out a 9.8.0+ toolkit against a 9.7.0 or older agent.

The following scenarios are supported for tracing assistance.

Continue Tracing from Client

The WebFluxSkyWalkingOperators#continueTracing provides manual tracing continuous capabilities to adopt native Webflux APIs

With apm-toolkit-webflux-5.x (Reactor 3.1.3 - 3.4). Mono#subscriberContext was removed in Reactor 3.5, so this form does not compile on Spring Boot 3.x/4.x:

    @GetMapping("/testcase/annotation/mono/onnext") 
    public Mono<String> monoOnNext(@RequestBody(required = false) String body) {
        return Mono.subscriberContext()
            .flatMap(ctx -> WebFluxSkyWalkingOperators.continueTracing(ctx, () -> {
                visit("http://localhost:" + serverPort + "/testcase/success");
                return Mono.just("Hello World");
            }));
    }

The ServerWebExchange overload takes no Reactor context, so it is identical on both generations:

    @GetMapping("/login/userFunctions")
    public Mono<Response<FunctionInfoResult>> functionInfo(ServerWebExchange exchange, @RequestParam String userId) {
        return ReactiveSecurityContextHolder.getContext()
            .flatMap(context ->  {
                return exchange.getSession().map(session -> WebFluxSkyWalkingOperators.continueTracing(exchange, () -> handle(session, userId)));
            });
    }

    private Response<FunctionInfoResult> handle(WebSession session, String userId) {
        //...dubbo rpc    
    }

With apm-toolkit-webflux-6.x (Reactor 3.5+). Mono#deferContextual and Context#of(ContextView) were added in Reactor 3.4, so this form requires Reactor 3.4 or later:

    Mono.just("key").subscribeOn(Schedulers.boundedElastic())
        .doOnEach(WebFluxSkyWalkingOperators.continueTracing(SignalType.ON_NEXT, () -> log.info("test log with tid")))
        .flatMap(key -> Mono.deferContextual(ctx -> WebFluxSkyWalkingOperators.continueTracing(Context.of(ctx), () -> {
                redis.hasKey(key);
                return Mono.just("SUCCESS");
            })
        ));
...

Fetch trace context relative IDs

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        // fetch trace ID
        String traceId = WebFluxSkyWalkingTraceContext.traceId(exchange);
        
        // fetch segment ID
        String segmentId = WebFluxSkyWalkingTraceContext.segmentId(exchange);
        
        // fetch span ID
        int spanId = WebFluxSkyWalkingTraceContext.spanId(exchange);
        
        return chain.filter(exchange);
    }

Manipulate Correlation Context

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){
        // Set correlation data can be retrieved by upstream nodes.
        WebFluxSkyWalkingTraceContext.putCorrelation(exchange, "key1", "value");
        
        // Get correlation data
        Optional<String> value2 = WebFluxSkyWalkingTraceContext.getCorrelation(exchange, "key2");
        
        // dosomething...
        
        return chain.filter(exchange);
    }

Sample codes only