'suppress stacktrace from spring webclient/netty layer

In one of the apps my team manages, there's a GraphQL orchestration layer that calls a downstream service. We use Spring's webclient for it.

WebClient Config.

WebClient.Builder webClientBuilder(MetricsWebClientCustomizer metricsCustomizer) {
        final HttpClient httpClient = HttpClient.create(ConnectionProvider.fixed("webClientPool", maxConnections))
                .tcpConfiguration(client ->
                        client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeoutMillis)
                                .option(EpollChannelOption.TCP_KEEPIDLE, tcpKeepIdleInSec)
                                .option(EpollChannelOption.TCP_KEEPINTVL, tcpKeepIntvlInSec)
                                .option(EpollChannelOption.TCP_KEEPCNT, tcpKeepCount)
                                .doOnConnected(conn -> conn
                                        .addHandlerLast(new ReadTimeoutHandler(readTimeoutInSec))
                ));

        final WebClient.Builder webClient = WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient));

        metricsCustomizer.customize(webClient);

        return webClient;
    }


return  client.post()
        .uri(uriBuilder -> buildUri())
        .contentType(MediaType.APPLICATION_JSON)
        .body(BodyInserters.fromObject(request))
        .retrieve()
        .bodyToMono(Result.class)
        .compose(CircuitBreakerOperator.of(cb))
        .block(Duration.ofSeconds(blockDuration));

This setup works well. However, I see a lot of

io.netty.handler.timeout.ReadTimeoutException: null
    Suppressed: java.lang.Exception: #block terminated with an error
        at reactor.core.publisher. .blockingGet(BlockingSingleSubscriber.java:133)
        at reactor.core.publisher.Mono.block(Mono.java:1518)
        at com.xxxx.c.g.xx.client.Client.get(Client.java:293)
        at com.xxxx.c.g.xx.resolver.impl.xxQueryImpl.lambda$xx$171(xxQueryImpl.java:2187)
        at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:149)

Every timeout results in this chunky stacktrace. It's the same message that gets repeated. Does give any useful info. Is there a way to get WebClient/Netty print this once and ignore the rest?

BlockingSingleSubscriber.blockingGet seems to be doing this. Keeps track of previous exceptions.

Throwable e = this.error;
            if (e != null) {
                RuntimeException re = Exceptions.propagate(e);
                re.addSuppressed(new Exception("#block terminated with an error"));
                throw re;
            } else {
                return this.value;
            }

I tried adding error handlers to the calling function bodyToMono(Result.class).doOnError("log").block();

This results in the line "log" from the doOnError consumer getting printed along with the chunky stacktraces.

Any ideas?

Full stacktrace: https://pastebin.com/kdpspCEY



Solution 1:[1]

Not sure if you've solved the issue yet, but I had the same problem. For anyone with a similar issue, I solved it by setting the following in the application.properties file:

# Logging Information
logging.level.reactor.netty=off

This disabled Reactor Netty internal logging, which was a bit verbose for what I needed.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jaller200