Skip to content

Commit

Permalink
LOGBACK-942 Update SocketAppender to wait up to a configurable amount…
Browse files Browse the repository at this point in the history
… of milliseconds before dropping a log event.
  • Loading branch information
ericdahl committed Feb 2, 2014
1 parent 8c26f3b commit 6461fd3
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 3 deletions.
@@ -0,0 +1,94 @@
package ch.qos.logback.classic.net;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import ch.qos.logback.core.testUtil.RandomUtil;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class SocketAppenderLostMessagesTest {

@Test
public void testSynchronousSocketAppender() throws Exception {

SocketAppender socketAppender = new SocketAppender();
socketAppender.setReconnectionDelay(1000);
socketAppender.setIncludeCallerData(true);

runTest(socketAppender);
}

@Test
public void testSmallQueueSocketAppender() throws Exception {

SocketAppender socketAppender = new SocketAppender();
socketAppender.setReconnectionDelay(1000);
socketAppender.setQueueSize(25);
socketAppender.setIncludeCallerData(true);

runTest(socketAppender);
}

@Test
public void testLargeQueueSocketAppender() throws Exception {

SocketAppender socketAppender = new SocketAppender();
socketAppender.setReconnectionDelay(1000);
socketAppender.setQueueSize(25000);
socketAppender.setIncludeCallerData(true);

runTest(socketAppender);
}

public void runTest(SocketAppender socketAppender) throws Exception {
final int port = RandomUtil.getRandomServerPort();

LoggerContext serverLoggerContext = new LoggerContext();
serverLoggerContext.setName("serverLoggerContext");

ListAppender<ILoggingEvent> listAppender = new ListAppender<ILoggingEvent>();
listAppender.setContext(serverLoggerContext);
listAppender.start();

Logger serverLogger = serverLoggerContext.getLogger(getClass());
serverLogger.setAdditive(false);
serverLogger.addAppender(listAppender);


LoggerContext loggerContext = new LoggerContext();
loggerContext.setName("clientLoggerContext");
socketAppender.setContext(loggerContext);


SimpleSocketServer simpleSocketServer = new SimpleSocketServer(serverLoggerContext, port);
simpleSocketServer.start();

Thread.sleep(1000);

socketAppender.setPort(port);
socketAppender.setRemoteHost("localhost");
socketAppender.setReconnectionDelay(1000);
socketAppender.setIncludeCallerData(true);
socketAppender.start();
assertTrue(socketAppender.isStarted());

Logger logger = loggerContext.getLogger(getClass());
logger.setAdditive(false);
logger.addAppender(socketAppender);


for (int i = 0; i < 10000; ++i) {
logger.info("hello");
}

Thread.sleep(1000);

assertEquals(10000, listAppender.list.size());
loggerContext.stop();
simpleSocketServer.close();
}
}
Expand Up @@ -27,6 +27,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;


import javax.net.SocketFactory;
Expand Down Expand Up @@ -70,12 +71,19 @@ public abstract class AbstractSocketAppender<E> extends AppenderBase<E>
*/
private static final int DEFAULT_ACCEPT_CONNECTION_DELAY = 5000;

/**
* Default timeout for how long to wait when inserting an event into
* the BlockingQueue.
*/
private static final int DEFAULT_EVENT_DELAY_TIMEOUT = 3000;

private String remoteHost;
private int port = DEFAULT_PORT;
private InetAddress address;
private int reconnectionDelay = DEFAULT_RECONNECTION_DELAY;
private int queueSize = DEFAULT_QUEUE_SIZE;
private int acceptConnectionTimeout = DEFAULT_ACCEPT_CONNECTION_DELAY;
private int eventDelayLimit = DEFAULT_EVENT_DELAY_TIMEOUT;

private BlockingQueue<E> queue;
private String peerId;
Expand Down Expand Up @@ -168,8 +176,17 @@ public void stop() {
*/
@Override
protected void append(E event) {
if (event == null || !isStarted()) return;
queue.offer(event);
if (event == null || !isStarted()) return;

try {
final boolean inserted = queue.offer(event, eventDelayLimit, TimeUnit.MILLISECONDS);
if (!inserted) {
addInfo("Dropping event due to timeout limit of [" + eventDelayLimit +
"] milliseconds being exceeded");
}
} catch (InterruptedException e) {
addError("Interrupted while appending event to SocketAppender", e);
}
}

/**
Expand Down Expand Up @@ -407,13 +424,31 @@ public int getReconnectionDelay() {
public void setQueueSize(int queueSize) {
this.queueSize = queueSize;
}

/**
* Returns the value of the <b>queueSize</b> property.
*/
public int getQueueSize() {
return queueSize;
}

/**
* The <b>eventDelayLimit</b> takes a non-negative integer representing the
* number of milliseconds to allow the appender to block if the underlying
* BlockingQueue is full. Once this limit is reached, the event is dropped.
*
* @param eventDelayLimit the event delay limit (in milliseconds)
*/
public void setEventDelayLimit(int eventDelayLimit) {
this.eventDelayLimit = eventDelayLimit;
}

/**
* Returns the value of the <b>eventDelayLimit</b> property.
*/
public int getEventDelayLimit() {
return eventDelayLimit;
}

/**
* Sets the timeout that controls how long we'll wait for the remote
Expand Down

0 comments on commit 6461fd3

Please sign in to comment.