svn commit: r580 - in logback/trunk/logback-classic/src: main/java/ch/qos/logback/classic/net test/java/ch/qos/logback/classic/net

Author: seb Date: Wed Sep 13 19:54:25 2006 New Revision: 580 Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java Log: - code reformat in SocketAppender - updated test so that it does not tests serialization but only appender behaviour. Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java Wed Sep 13 19:54:25 2006 @@ -99,299 +99,299 @@ public class SocketAppender extends AppenderBase { - /** - * The default port number of remote logging server (4560). - */ - static final int DEFAULT_PORT = 4560; - - /** - * The default reconnection delay (30000 milliseconds or 30 seconds). - */ - static final int DEFAULT_RECONNECTION_DELAY = 30000; - - /** - * We remember host name as String in addition to the resolved InetAddress so - * that it can be returned via getOption(). - */ - String remoteHost; - - InetAddress address; - int port = DEFAULT_PORT; - ObjectOutputStream oos; - int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; - - private Connector connector; - - int counter = 0; - - // reset the ObjectOutputStream every 70 calls - private static final int RESET_FREQUENCY = 70; - - public SocketAppender() { - } - - /** - * Connects to remote server at <code>address</code> and <code>port</code>. - */ - public SocketAppender(InetAddress address, int port) { - this.address = address; - this.remoteHost = address.getHostName(); - this.port = port; - // connect(address, port); - } - - /** - * Connects to remote server at <code>host</code> and <code>port</code>. - */ - public SocketAppender(String host, int port) { - this.port = port; - this.address = getAddressByName(host); - this.remoteHost = host; - // connect(address, port); - } - - // /** - // * Connect to the specified <b>RemoteHost</b> and <b>Port</b>. - // */ - // public void activateOptions() { - // connect(address, port); - // } - - /** - * Start this appender. - */ - public void start() { - int errorCount = 0; - if (port == 0) { - errorCount++; - addError("No port was configured for appender" + name); - } - - if (address == null) { - errorCount++; - addError("No remote address was configured for appender" + name); - } - - connect(address, port); - - if (errorCount == 0) { - this.started = true; - } - } - - /** - * Strop this appender. - * - * <p> - * This will mark the appender as closed and call then {@link #cleanUp} - * method. - */ - @Override - public void stop() { - if (!isStarted()) - return; - - this.started = false; - cleanUp(); - } - - /** - * Drop the connection to the remote host and release the underlying connector - * thread if it has been created - */ - public void cleanUp() { - if (oos != null) { - try { - oos.close(); - } catch (IOException e) { - addError("Could not close oos.", e); - } - oos = null; - } - if (connector != null) { - addInfo("Interrupting the connector."); - connector.interrupted = true; - connector = null; // allow gc - } - } - - void connect(InetAddress address, int port) { - if (this.address == null) - return; - try { - // First, close the previous connection if any. - cleanUp(); - oos = new ObjectOutputStream(new Socket(address, port).getOutputStream()); - } catch (IOException e) { - - String msg = "Could not connect to remote logback server at [" - + address.getHostName() + "]."; - if (reconnectionDelay > 0) { - msg += " We will try again later."; - fireConnector(); // fire the connector thread - } - addError(msg, e); - } - } - - @Override - protected void append(Object event) { - - if (event == null) - return; - - if (address == null) { - addError("No remote host is set for SocketAppender named \"" + this.name - + "\"."); - return; - } - - if (oos != null) { - try { - oos.writeObject(event); - //addInfo("=========Flushing."); - oos.flush(); - if (++counter >= RESET_FREQUENCY) { - counter = 0; - // Failing to reset the object output stream every now and - // then creates a serious memory leak. - // System.err.println("Doing oos.reset()"); - oos.reset(); - } - } catch (IOException e) { - oos = null; - addWarn("Detected problem with connection: " + e); - if (reconnectionDelay > 0) { - fireConnector(); - } - } - } - } - - void fireConnector() { - if (connector == null) { - addInfo("Starting a new connector thread."); - connector = new Connector(); - connector.setDaemon(true); - connector.setPriority(Thread.MIN_PRIORITY); - connector.start(); - } - } - - static InetAddress getAddressByName(String host) { - try { - return InetAddress.getByName(host); - } catch (Exception e) { - // addError("Could not find address of [" + host + "].", e); - return null; - } - } - - /** - * The <b>RemoteHost</b> option takes a string value which should be the host - * name of the server where a {@link SocketNode} is running. - */ - public void setRemoteHost(String host) { - address = getAddressByName(host); - remoteHost = host; - } - - /** - * Returns value of the <b>RemoteHost</b> option. - */ - public String getRemoteHost() { - return remoteHost; - } - - /** - * The <b>Port</b> option takes a positive integer representing the port - * where the server is waiting for connections. - */ - public void setPort(int port) { - this.port = port; - } - - /** - * Returns value of the <b>Port</b> option. - */ - public int getPort() { - return port; - } - - /** - * The <b>ReconnectionDelay</b> option takes a positive integer representing - * the number of milliseconds to wait between each failed connection attempt - * to the server. The default value of this option is 30000 which corresponds - * to 30 seconds. - * - * <p> - * Setting this option to zero turns off reconnection capability. - */ - public void setReconnectionDelay(int delay) { - this.reconnectionDelay = delay; - } - - /** - * Returns value of the <b>ReconnectionDelay</b> option. - */ - public int getReconnectionDelay() { - return reconnectionDelay; - } - - public Layout getLayout() { - return null; - } - - public void setLayout(Layout layout) { - } - - /** - * The Connector will reconnect when the server becomes available again. It - * does this by attempting to open a new connection every - * <code>reconnectionDelay</code> milliseconds. - * - * <p> - * It stops trying whenever a connection is established. It will restart to - * try reconnect to the server when previpously open connection is droppped. - * - * @author Ceki Gülcü - * @since 0.8.4 - */ - class Connector extends Thread { - - boolean interrupted = false; - - public void run() { - Socket socket; - while (!interrupted) { - try { - sleep(reconnectionDelay); - addInfo("Attempting connection to " + address.getHostName()); - socket = new Socket(address, port); - synchronized (this) { - oos = new ObjectOutputStream(socket.getOutputStream()); - connector = null; - addInfo("Connection established. Exiting connector thread."); - break; - } - } catch (InterruptedException e) { - addInfo("Connector interrupted. Leaving loop."); - return; - } catch (java.net.ConnectException e) { - addInfo("Remote host " + address.getHostName() - + " refused connection."); - } catch (IOException e) { - addInfo("Could not connect to " + address.getHostName() - + ". Exception is " + e); - } - } - // addInfo("Exiting Connector.run() method."); - } - - /** - * public void finalize() { LogLog.debug("Connector finalize() has been - * called."); } - */ - } + /** + * The default port number of remote logging server (4560). + */ + static final int DEFAULT_PORT = 4560; + + /** + * The default reconnection delay (30000 milliseconds or 30 seconds). + */ + static final int DEFAULT_RECONNECTION_DELAY = 30000; + + /** + * We remember host name as String in addition to the resolved InetAddress so + * that it can be returned via getOption(). + */ + String remoteHost; + + InetAddress address; + int port = DEFAULT_PORT; + ObjectOutputStream oos; + int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; + + private Connector connector; + + int counter = 0; + + // reset the ObjectOutputStream every 70 calls + private static final int RESET_FREQUENCY = 70; + + public SocketAppender() { + } + + /** + * Connects to remote server at <code>address</code> and <code>port</code>. + */ + public SocketAppender(InetAddress address, int port) { + this.address = address; + this.remoteHost = address.getHostName(); + this.port = port; + // connect(address, port); + } + + /** + * Connects to remote server at <code>host</code> and <code>port</code>. + */ + public SocketAppender(String host, int port) { + this.port = port; + this.address = getAddressByName(host); + this.remoteHost = host; + // connect(address, port); + } + + // /** + // * Connect to the specified <b>RemoteHost</b> and <b>Port</b>. + // */ + // public void activateOptions() { + // connect(address, port); + // } + + /** + * Start this appender. + */ + public void start() { + int errorCount = 0; + if (port == 0) { + errorCount++; + addError("No port was configured for appender" + name); + } + + if (address == null) { + errorCount++; + addError("No remote address was configured for appender" + name); + } + + connect(address, port); + + if (errorCount == 0) { + this.started = true; + } + } + + /** + * Strop this appender. + * + * <p> + * This will mark the appender as closed and call then {@link #cleanUp} + * method. + */ + @Override + public void stop() { + if (!isStarted()) + return; + + this.started = false; + cleanUp(); + } + + /** + * Drop the connection to the remote host and release the underlying connector + * thread if it has been created + */ + public void cleanUp() { + if (oos != null) { + try { + oos.close(); + } catch (IOException e) { + addError("Could not close oos.", e); + } + oos = null; + } + if (connector != null) { + addInfo("Interrupting the connector."); + connector.interrupted = true; + connector = null; // allow gc + } + } + + void connect(InetAddress address, int port) { + if (this.address == null) + return; + try { + // First, close the previous connection if any. + cleanUp(); + oos = new ObjectOutputStream(new Socket(address, port).getOutputStream()); + } catch (IOException e) { + + String msg = "Could not connect to remote logback server at [" + + address.getHostName() + "]."; + if (reconnectionDelay > 0) { + msg += " We will try again later."; + fireConnector(); // fire the connector thread + } + addError(msg, e); + } + } + + @Override + protected void append(Object event) { + + if (event == null) + return; + + if (address == null) { + addError("No remote host is set for SocketAppender named \"" + this.name + + "\"."); + return; + } + + if (oos != null) { + try { + oos.writeObject(event); + // addInfo("=========Flushing."); + oos.flush(); + if (++counter >= RESET_FREQUENCY) { + counter = 0; + // Failing to reset the object output stream every now and + // then creates a serious memory leak. + // System.err.println("Doing oos.reset()"); + oos.reset(); + } + } catch (IOException e) { + oos = null; + addWarn("Detected problem with connection: " + e); + if (reconnectionDelay > 0) { + fireConnector(); + } + } + } + } + + void fireConnector() { + if (connector == null) { + addInfo("Starting a new connector thread."); + connector = new Connector(); + connector.setDaemon(true); + connector.setPriority(Thread.MIN_PRIORITY); + connector.start(); + } + } + + static InetAddress getAddressByName(String host) { + try { + return InetAddress.getByName(host); + } catch (Exception e) { + // addError("Could not find address of [" + host + "].", e); + return null; + } + } + + /** + * The <b>RemoteHost</b> option takes a string value which should be the host + * name of the server where a {@link SocketNode} is running. + */ + public void setRemoteHost(String host) { + address = getAddressByName(host); + remoteHost = host; + } + + /** + * Returns value of the <b>RemoteHost</b> option. + */ + public String getRemoteHost() { + return remoteHost; + } + + /** + * The <b>Port</b> option takes a positive integer representing the port + * where the server is waiting for connections. + */ + public void setPort(int port) { + this.port = port; + } + + /** + * Returns value of the <b>Port</b> option. + */ + public int getPort() { + return port; + } + + /** + * The <b>ReconnectionDelay</b> option takes a positive integer representing + * the number of milliseconds to wait between each failed connection attempt + * to the server. The default value of this option is 30000 which corresponds + * to 30 seconds. + * + * <p> + * Setting this option to zero turns off reconnection capability. + */ + public void setReconnectionDelay(int delay) { + this.reconnectionDelay = delay; + } + + /** + * Returns value of the <b>ReconnectionDelay</b> option. + */ + public int getReconnectionDelay() { + return reconnectionDelay; + } + + public Layout getLayout() { + return null; + } + + public void setLayout(Layout layout) { + } + + /** + * The Connector will reconnect when the server becomes available again. It + * does this by attempting to open a new connection every + * <code>reconnectionDelay</code> milliseconds. + * + * <p> + * It stops trying whenever a connection is established. It will restart to + * try reconnect to the server when previpously open connection is droppped. + * + * @author Ceki Gülcü + * @since 0.8.4 + */ + class Connector extends Thread { + + boolean interrupted = false; + + public void run() { + Socket socket; + while (!interrupted) { + try { + sleep(reconnectionDelay); + addInfo("Attempting connection to " + address.getHostName()); + socket = new Socket(address, port); + synchronized (this) { + oos = new ObjectOutputStream(socket.getOutputStream()); + connector = null; + addInfo("Connection established. Exiting connector thread."); + break; + } + } catch (InterruptedException e) { + addInfo("Connector interrupted. Leaving loop."); + return; + } catch (java.net.ConnectException e) { + addInfo("Remote host " + address.getHostName() + + " refused connection."); + } catch (IOException e) { + addInfo("Could not connect to " + address.getHostName() + + ". Exception is " + e); + } + } + // addInfo("Exiting Connector.run() method."); + } + + /** + * public void finalize() { LogLog.debug("Connector finalize() has been + * called."); } + */ + } } Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java ============================================================================== --- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java (original) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java Wed Sep 13 19:54:25 2006 @@ -1,5 +1,10 @@ package ch.qos.logback.classic.net; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.util.Map; import junit.framework.TestCase; @@ -13,126 +18,130 @@ public class SocketAppenderTest extends TestCase { - private LoggerContext lc; - private MockSocketServer mockSocketServer; - - public void testStartFailNoRemoteHost() { - lc = new LoggerContext(); - SocketAppender appender = new SocketAppender(); - appender.setContext(lc); - appender.setPort(123); - appender.start(); - assertEquals(1, lc.getStatusManager().getCount()); - } - - public void testRecieveMessage() throws InterruptedException { - startServer(1); - configureClient(); - - Logger logger = lc.getLogger(LoggerContext.ROOT_NAME); - logger.debug("test msg"); - - // Wait max 2 seconds for mock server to finish. However, it should - // finish much sooner than that. - mockSocketServer.join(2000); - assertTrue(mockSocketServer.finished); - assertEquals(1, mockSocketServer.loggingEventList.size()); - - LoggingEvent remoteEvent = mockSocketServer.loggingEventList.get(0); - assertEquals("test msg", remoteEvent.getMessage()); - assertEquals(Level.DEBUG, remoteEvent.getLevel()); - } - - public void testRecieveWithContext() throws InterruptedException { - startServer(1); - configureClient(); - - Logger logger = lc.getLogger(LoggerContext.ROOT_NAME); - logger.debug("test msg"); - - // Wait max 2 seconds for mock server to finish. However, it should - // finish much sooner than that. - mockSocketServer.join(2000); - assertTrue(mockSocketServer.finished); - assertEquals(1, mockSocketServer.loggingEventList.size()); - - LoggingEvent remoteEvent = mockSocketServer.loggingEventList.get(0); - - LoggerRemoteView loggerRemoteView = remoteEvent.getLoggerRemoteView(); - assertNotNull(loggerRemoteView); - assertEquals("root", loggerRemoteView.getName()); - - LoggerContextRemoteView loggerContextRemoteView = loggerRemoteView.getLoggerContextView(); - assertNotNull(loggerContextRemoteView); - assertEquals("test", loggerContextRemoteView.getName()); - Map<String, String> props = loggerContextRemoteView.getPropertyMap(); - assertEquals("testValue", props.get("testKey")); - } - - - public void testMessageWithMDC() throws InterruptedException { - startServer(1); - configureClient(); - - Logger logger = lc.getLogger(LoggerContext.ROOT_NAME); - - MDC.put("key", "testValue"); - logger.debug("test msg"); - - // Wait max 2 seconds for mock server to finish. However, it should - // finish much sooner than that. - mockSocketServer.join(2000); - assertTrue(mockSocketServer.finished); - assertEquals(1, mockSocketServer.loggingEventList.size()); - - LoggingEvent remoteEvent = mockSocketServer.loggingEventList.get(0); - Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap(); - assertEquals("testValue", MDCPropertyMap.get("key")); - } - - public void testMessageWithUpdatedMDC() throws InterruptedException { - startServer(2); - configureClient(); - - Logger logger = lc.getLogger(LoggerContext.ROOT_NAME); - - MDC.put("key", "testValue"); - logger.debug("test msg"); - - MDC.put("key", "updatedTestValue"); - logger.debug("test msg 2"); - - // Wait max 2 seconds for mock server to finish. However, it should - // finish much sooner than that. - mockSocketServer.join(2000); - assertTrue(mockSocketServer.finished); - assertEquals(2, mockSocketServer.loggingEventList.size()); - - //We observe the second logging event. It should provide us with - //the updated MDC property. - LoggingEvent remoteEvent = mockSocketServer.loggingEventList.get(1); - Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap(); - assertEquals("updatedTestValue", MDCPropertyMap.get("key")); - } - - private void startServer(int expectedEventNumber) throws InterruptedException { - mockSocketServer = new MockSocketServer(expectedEventNumber); - mockSocketServer.start(); - // give MockSocketServer head start - Thread.sleep(100); - } - - private void configureClient() { - lc = new LoggerContext(); - lc.setName("test"); - lc.setProperty("testKey", "testValue"); - Logger root = lc.getLogger(LoggerContext.ROOT_NAME); - SocketAppender socketAppender = new SocketAppender(); - socketAppender.setContext(lc); - socketAppender.setName("socket"); - socketAppender.setPort(4560); - socketAppender.setRemoteHost("localhost"); - root.addAppender(socketAppender); - socketAppender.start(); - } + ByteArrayOutputStream bos; + ObjectInputStream inputStream; + SocketAppender appender; + Logger logger; + + LoggerContext lc; + MockSocketServer mockSocketServer; + + public void setUp() throws Exception { + lc = new LoggerContext(); + lc.setName("test"); + lc.setProperty("testKey", "testValue"); + appender = new SocketAppender(); + appender.setPort(123); + appender.setContext(lc); + appender.setRemoteHost("localhost"); + appender.start(); + logger = lc.getLogger(LoggerContext.ROOT_NAME); + logger.addAppender(appender); + } + + public void testStartFailNoRemoteHost() { + lc = new LoggerContext(); + SocketAppender appender = new SocketAppender(); + appender.setContext(lc); + appender.setPort(123); + appender.start(); + assertEquals(1, lc.getStatusManager().getCount()); + } + + public void testRecieveMessage() throws InterruptedException, IOException, + ClassNotFoundException { + + //create the byte output stream + bos = new ByteArrayOutputStream() ; + appender.oos = new ObjectOutputStream(bos); + + LoggingEvent event = createLoggingEvent(); + appender.append(event); + + //create the input stream based on the ouput stream + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + inputStream = new ObjectInputStream(bis); + + LoggingEvent remoteEvent = (LoggingEvent) inputStream.readObject(); + + assertEquals("test message", remoteEvent.getMessage()); + assertEquals(Level.DEBUG, remoteEvent.getLevel()); + } + + public void testRecieveWithContext() throws InterruptedException, IOException, ClassNotFoundException { + + //create the byte output stream + bos = new ByteArrayOutputStream() ; + appender.oos = new ObjectOutputStream(bos); + + LoggingEvent event = createLoggingEvent(); + appender.append(event); + + //create the input stream based on the ouput stream + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + inputStream = new ObjectInputStream(bis); + + LoggingEvent remoteEvent = (LoggingEvent) inputStream.readObject(); + + LoggerRemoteView loggerRemoteView = remoteEvent.getLoggerRemoteView(); + assertNotNull(loggerRemoteView); + assertEquals("root", loggerRemoteView.getName()); + + LoggerContextRemoteView loggerContextRemoteView = loggerRemoteView + .getLoggerContextView(); + assertNotNull(loggerContextRemoteView); + assertEquals("test", loggerContextRemoteView.getName()); + Map<String, String> props = loggerContextRemoteView.getPropertyMap(); + assertEquals("testValue", props.get("testKey")); + } + + public void testMessageWithMDC() throws InterruptedException, IOException, ClassNotFoundException { + //create the byte output stream + bos = new ByteArrayOutputStream() ; + appender.oos = new ObjectOutputStream(bos); + + MDC.put("key", "testValue"); + LoggingEvent event = createLoggingEvent(); + appender.append(event); + + //create the input stream based on the ouput stream + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + inputStream = new ObjectInputStream(bis); + + LoggingEvent remoteEvent = (LoggingEvent) inputStream.readObject(); + + Map<String, String> MDCPropertyMap = remoteEvent.getMDCPropertyMap(); + assertEquals("testValue", MDCPropertyMap.get("key")); + } + + public void testMessageWithUpdatedMDC() throws InterruptedException, IOException, ClassNotFoundException { + //create the byte output stream + bos = new ByteArrayOutputStream() ; + appender.oos = new ObjectOutputStream(bos); + + MDC.put("key", "testValue"); + LoggingEvent event = createLoggingEvent(); + appender.append(event); + + MDC.put("key", "updatedTestValue"); + event = createLoggingEvent(); + appender.append(event); + + //create the input stream based on the ouput stream + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + inputStream = new ObjectInputStream(bis); + + @SuppressWarnings("unused") + LoggingEvent remoteEvent1 = (LoggingEvent) inputStream.readObject(); + LoggingEvent remoteEvent2 = (LoggingEvent) inputStream.readObject(); + + Map<String, String> MDCPropertyMap = remoteEvent2.getMDCPropertyMap(); + assertEquals("updatedTestValue", MDCPropertyMap.get("key")); + } + + private LoggingEvent createLoggingEvent() { + LoggingEvent le = new LoggingEvent(this.getClass().getName(), logger, + Level.DEBUG, "test message", null, null); + return le; + } }
participants (1)
-
noreply.seb@qos.ch