From 749488e718fa5d47068fdd00854b4af2a99c3cfd Mon Sep 17 00:00:00 2001
From: Oliver Siegmar <oliver@siegmar.net>
Date: Mon, 8 Oct 2012 13:14:35 +0200
Subject: [PATCH] Added timeout options to SocketAppenderBase

---
 .../qos/logback/core/net/SocketAppenderBase.java   |   63 +++++++++++++++++++-
 1 file changed, 61 insertions(+), 2 deletions(-)

diff --git a/logback-core/src/main/java/ch/qos/logback/core/net/SocketAppenderBase.java b/logback-core/src/main/java/ch/qos/logback/core/net/SocketAppenderBase.java
index eeaacea..a7b3533 100644
--- a/logback-core/src/main/java/ch/qos/logback/core/net/SocketAppenderBase.java
+++ b/logback-core/src/main/java/ch/qos/logback/core/net/SocketAppenderBase.java
@@ -18,6 +18,7 @@ import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.Socket;
 
 import ch.qos.logback.core.AppenderBase;
@@ -45,6 +46,16 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> {
   static final int DEFAULT_RECONNECTION_DELAY = 30000;
 
   /**
+   * The default socket connect timeout (infinite timeout for backwards compatibility).
+   */
+  static final int DEFAULT_SOCKET_CONNECT_TIMEOUT = 0;
+
+  /**
+   * The default socket send timeout (infinite timeout for backwards compatibility).
+   */
+  static final int DEFAULT_SOCKET_SEND_TIMEOUT = 0;
+
+  /**
    * We remember host name as String in addition to the resolved InetAddress so
    * that it can be returned via getOption().
    */
@@ -54,6 +65,8 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> {
   protected int port = DEFAULT_PORT;
   protected ObjectOutputStream oos;
   protected int reconnectionDelay = DEFAULT_RECONNECTION_DELAY;
+  protected int socketConnectTimeout = DEFAULT_SOCKET_CONNECT_TIMEOUT;
+  protected int socketSendTimeout = DEFAULT_SOCKET_SEND_TIMEOUT;
 
   private Connector connector;
 
@@ -127,7 +140,10 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> {
     try {
       // First, close the previous connection if any.
       cleanUp();
-      oos = new ObjectOutputStream(new Socket(address, port).getOutputStream());
+      Socket socket = new Socket();
+      socket.setSoTimeout(socketSendTimeout);
+      socket.connect(new InetSocketAddress(address, port), socketConnectTimeout);
+      oos = new ObjectOutputStream(socket.getOutputStream());
     } catch (IOException e) {
 
       String msg = "Could not connect to remote logback server at ["
@@ -255,6 +271,47 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> {
     return reconnectionDelay;
   }
 
+  /**
+   * The <b>socketConnectTimeout</b> property takes a positive integer representing
+   * the number of milliseconds to wait for establishing the socket connection.
+   * If no connection could be established within this period, a
+   * {@link java.net.SocketTimeoutException} will be thrown. The default value of
+   * this option is 0 which turns off the timeout (infinite timeout).
+   *
+   * <p>
+   * Setting this option to zero turns off the timeout (infinite timeout).
+   */
+  public void setSocketConnectTimeout(int timeout) {
+    this.socketConnectTimeout = timeout;
+  }
+
+  /**
+   * Returns value of the <b>socketConnectTimeout</b> property.
+   */
+  public int getSocketConnectTimeout() {
+    return socketConnectTimeout;
+  }
+
+  /**
+   * The <b>socketSendTimeout</b> property takes a positive integer representing
+   * the number of milliseconds to wait for sending data through the socket connection.
+   * If no data could be send within this period, a
+   * {@link java.net.SocketTimeoutException} will be thrown. The default value of
+   * this option is 0 which turns off the timeout (infinite timeout).
+   *
+   * <p>
+   * Setting this option to zero turns off the timeout (infinite timeout).
+   */
+  public void setSocketSendTimeout(int timeout) {
+    this.socketSendTimeout = timeout;
+  }
+
+  /**
+   * Returns value of the <b>socketSendTimeout</b> property.
+   */
+  public int getSocketSendTimeout() {
+    return socketSendTimeout;
+  }
   
   /**
    * The Connector will reconnect when the server becomes available again. It
@@ -278,7 +335,9 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> {
         try {
           sleep(reconnectionDelay);
           addInfo("Attempting connection to " + address.getHostName());
-          socket = new Socket(address, port);
+          socket = new Socket();
+          socket.setSoTimeout(socketSendTimeout);
+          socket.connect(new InetSocketAddress(address, port), socketConnectTimeout);
           synchronized (this) {
             oos = new ObjectOutputStream(socket.getOutputStream());
             connector = null;
-- 
1.7.9.5

