From ae2f9bcddede1bb1e090eef4d62f97c23eb41b1c Mon Sep 17 00:00:00 2001 From: Andrii Rosa Date: Thu, 8 Nov 2018 19:28:32 -0500 Subject: [PATCH] Don't log connection close exceptions in Drift server --- .../netty/server/ThriftServerHandler.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drift-transport-netty/src/main/java/io/airlift/drift/transport/netty/server/ThriftServerHandler.java b/drift-transport-netty/src/main/java/io/airlift/drift/transport/netty/server/ThriftServerHandler.java index 91ab958f0..c1da2e509 100644 --- a/drift-transport-netty/src/main/java/io/airlift/drift/transport/netty/server/ThriftServerHandler.java +++ b/drift-transport-netty/src/main/java/io/airlift/drift/transport/netty/server/ThriftServerHandler.java @@ -44,6 +44,7 @@ import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelHandlerContext; +import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; @@ -53,8 +54,10 @@ import java.util.OptionalInt; import java.util.OptionalLong; import java.util.concurrent.ScheduledExecutorService; +import java.util.regex.Pattern; import static com.google.common.base.Defaults.defaultValue; +import static com.google.common.base.Strings.nullToEmpty; import static com.google.common.util.concurrent.Futures.immediateFailedFuture; import static com.google.common.util.concurrent.Futures.immediateFuture; import static com.google.common.util.concurrent.MoreExecutors.directExecutor; @@ -65,12 +68,16 @@ import static io.airlift.drift.protocol.TMessageType.REPLY; import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.regex.Pattern.CASE_INSENSITIVE; public class ThriftServerHandler extends ChannelDuplexHandler { private static final Logger log = Logger.get(ThriftServerHandler.class); + private static final Pattern CONNECTION_CLOSED_MESSAGE = Pattern.compile( + "^.*(?:connection.*(?:reset|closed|abort|broken)|broken.*pipe).*$", CASE_INSENSITIVE); + private final ServerMethodInvoker methodInvoker; private final ScheduledExecutorService timeoutExecutor; private final Duration requestTimeout; @@ -92,6 +99,15 @@ public void channelRead(ChannelHandlerContext context, Object message) context.fireChannelRead(message); } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) + { + // Don't log connection closed exceptions + if (!isConnectionClosed(cause)) { + log.error(cause); + } + } + private void messageReceived(ChannelHandlerContext context, ThriftFrame frame) { TChannelBufferInputTransport inputTransport = new TChannelBufferInputTransport(frame.getMessage()); @@ -398,4 +414,21 @@ private static void writeResponse( protocolWriter.writeMessageEnd(); } + + /* + * There is no good way of detecting connection closed exception + * + * This implementation is a simplified version of the implementation proposed + * in Netty: io.netty.handler.ssl.SslHandler#exceptionCaught + * + * This implementation ony checks a message with the regex, and doesn't do any + * more sophisticated matching, as the regex works in most of the cases. + */ + private boolean isConnectionClosed(Throwable t) + { + if (t instanceof IOException) { + return CONNECTION_CLOSED_MESSAGE.matcher(nullToEmpty(t.getMessage())).matches(); + } + return false; + } }