0

doOnSuccess method of Mono class is not logging the sleuth correlationId in logs. Response recieved from http://localhost:8080/testController/test is the log statement where correlationId should have been logged.

I have also checked the documentation of Mono class but could not figure out why doOnSuccess method is outside of sleuth.

DEBUG|CustomLogEvent||||[eb150c1d-1, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:49557] HTTP GET "/testController/test"
DEBUG|CustomLogEvent||||Received a request to uri [/testController/test]
DEBUG|CustomLogEvent||||Handled receive of span NoopSpan(91e1905bb164f0d5/91e1905bb164f0d5)
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|Route matched: 4b1a1440-160f-4429-902c-3f6508d2023c
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|Mapping [Exchange: GET http://localhost:8080/testController/test] to Route{id='4b1a1440-160f-4429-902c-3f6508d2023c', uri=http://localhost:9801, order=0, predicate=Paths: [/testController/**], match trailing slash: true, gatewayFilters=[], metadata={}}
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|[eb150c1d-1, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:49557] Mapped to org.springframework.cloud.gateway.handler.FilteringWebHandler@6e61d1ee
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|Sorted gatewayFilterFactories: [[GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@1291aab5}, order = -2147483648], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@13278a41}, order = -2147482648], [GatewayFilterAdapter{delegate=com.poc.gateway.filters.PreFilter@a3cba3a}, order = -2], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@5ca4dce5}, order = -1], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardPathFilter@7eb27768}, order = 0], [GatewayFilterAdapter{delegate=com.poc.gateway.filters.PostFilter@224d86d2}, order = 1], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@7d133fb7}, order = 10000], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.config.GatewayNoLoadBalancerClientAutoConfiguration$NoLoadBalancerClientFilter@5e3db14}, order = 10150], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@6169be09}, order = 2147483646], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter@2aea717c}, order = 2147483647], [GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@40bd0f8}, order = 2147483647]]
INFO|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|PreFilter executed.
INFO|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|PostFilter executed.
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|-Dio.netty.native.workdir: /var/folders/3r/hp4w8pn55yg5l9h4yv8pvrwh0000gn/T (io.netty.tmpdir)
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|-Dio.netty.native.deleteLibAfterLoading: true
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|-Dio.netty.native.tryPatchShadedId: true
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|Successfully loaded the library /var/folders/3r/hp4w8pn55yg5l9h4yv8pvrwh0000gn/T/libnetty_resolver_dns_native_macos_x86_647557281057916852695.dylib
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider: available
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|Creating a new [proxy] client pool [PoolFactory{evictionInterval=PT0S, leasingStrategy=fifo, maxConnections=2147483647, maxIdleTime=-1, maxLifeTime=-1, metricsEnabled=false, pendingAcquireMaxCount=-1, pendingAcquireTimeout=0}] for [localhost:9801]
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|[d3ca45ea] Created a new pooled channel, now: 0 active connections, 0 inactive connections and 0 pending acquire requests.
DEBUG|CustomLogEvent||91e1905bb164f0d5|91e1905bb164f0d5|[d3ca45ea] Initialized pipeline DefaultChannelPipeline{(reactor.left.httpCodec = io.netty.handler.codec.http.HttpClientCodec), (reactor.right.reactiveBridge = reactor.netty.channel.ChannelOperationsHandler)}
DEBUG|CustomLogEvent||||[d3ca45ea] Connecting to [localhost/127.0.0.1:9801].
DEBUG|CustomLogEvent||||[d3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] Registering pool release on close event for channel
DEBUG|CustomLogEvent||||[d3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] Channel connected, now: 1 active connections, 0 inactive connections and 0 pending acquire requests.
DEBUG|CustomLogEvent||||[d3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}, [connected])
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(GET{uri=/, connection=PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}}, [configured])
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] Handler is being applied: {uri=http://localhost:9801/testController/test, method=GET}
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(GET{uri=/testController/test, connection=PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}}, [request_prepared])
DEBUG|CustomLogEvent||||Handled send of the netty client span [NoopSpan(91e1905bb164f0d5/1ceb21c766fd48ac)] with parent [91e1905bb164f0d5/91e1905bb164f0d5]
DEBUG|CustomLogEvent||||[eb150c1d-1, L:/0:0:0:0:0:0:0:1:8080 - R:/0:0:0:0:0:0:0:1:49557] FluxReceive{pending=0, cancelled=false, inboundDone=true, inboundError=null}: subscribing inbound receiver
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(GET{uri=/testController/test, connection=PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}}, [request_sent])
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] Received response (auto-read:false) : [Content-Type=text/html;charset=UTF-8, Date=Tue, 21 Dec 2021 13:42:10 GMT, content-length=27]
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(GET{uri=/testController/test, connection=PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}}, [response_received])
INFO|CustomLogEvent||||Response recieved from http://localhost:8080/testController/test
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] FluxReceive{pending=0, cancelled=false, inboundDone=false, inboundError=null}: subscribing inbound receiver
DEBUG|CustomLogEvent||||[d3ca45ea-1, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] Received last HTTP packet
DEBUG|CustomLogEvent||||[d3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801] onStateChange(GET{uri=/testController/test, connection=PooledConnection{channel=[id: 0xd3ca45ea, L:/127.0.0.1:49558 - R:localhost/127.0.0.1:9801]}}, [response_completed])
DEBUG|CustomLogEvent||||Handle receive of the netty client span [NoopSpan(91e1905bb164f0d5/1ceb21c766fd48ac)]

Following is the code snippet of gateway service.

PreFilter.java

package com.poc.gateway.filters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

@Component
class PreFilter implements GlobalFilter, Ordered {
    
    Logger logger = LoggerFactory.getLogger(PreFilter.class);

    @Override
    public int getOrder() {
        return -2;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        logger.info("PreFilter executed.");
        return chain.filter(exchange);
    }

}

PostFilter.java

package com.poc.gateway.filters;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import reactor.core.publisher.Mono;

@Component
public class PostFilter implements GlobalFilter, Ordered{
    
    Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Override
    public int getOrder() {
        return 1;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        final String requestUrl = exchange.getRequest().getURI().toString();
        logger.info("PostFilter executed.");
        Mono<Void> output = chain.filter(exchange).doOnSuccess((consumer) ->
        logger.info("Response recieved from " + requestUrl));
        return output;
    }
}

AppConfig.java

package com.poc.gateway.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    
    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder builder) {
        return builder.routes()
                .route(r -> r.path("/testController/**")
                        .uri("http://localhost:9801"))
                .build();
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.1</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.poc</groupId>
    <artifactId>spring-gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-gateway</name>
    <description>Spring Gateway</description>
    <properties>
        <java.version>11</java.version>
        <spring-cloud.version>2021.0.0</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-log4j-2.13.2</artifactId>
            <version>1.7.2-alpha</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-api</artifactId>
            <version>1.7.1</version>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Thanks for your response.

shalabh
  • 85
  • 8
  • I think you lose the id because the execution of doOnSuccess is performed in different thread that doesn't posess the context you need (in this case, `ServerWebExchange exchange, GatewayFilterChain chain` objects). So just log in the filter method only, like you have done with other logging – Nick Dec 21 '21 at 17:24
  • Could you please try a different instrumentation mode for reactor https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/htmlsingle/spring-cloud-sleuth.html#sleuth-reactor-integration I recommend DECORATE_QUEUES – Jonatan Ivanov Dec 21 '21 at 20:18

0 Answers0