'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 |