This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Logback: the generic, reliable, fast and flexible logging framework.".
The branch, lbcore148 has been created at 45f7a6281a1f2a07b0f11ac79af72ccd7d8979a2 (commit) - Log ----------------------------------------------------------------- http://git.qos.ch/gitweb/?p=logback.git;a=commit;h=45f7a6281a1f2a07b0f11ac79af72ccd7d8979a2 http://github.com/ceki/logback/commit/45f7a6281a1f2a07b0f11ac79af72ccd7d8979a2 commit 45f7a6281a1f2a07b0f11ac79af72ccd7d8979a2 Author: Ceki Gulcu <c...@qos.ch> Date: Sat Apr 3 01:17:57 2010 +0200 ongoing work on migrating SocketAppender to resilientOS diff --git a/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java b/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java index 4f567a6..ac854d7 100644 --- a/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java +++ b/logback-access/src/main/java/ch/qos/logback/access/net/SocketAppender.java @@ -43,9 +43,7 @@ public class SocketAppender extends SocketAppenderBase<AccessEvent> { * 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; + this(address.getHostName(), port); } /** @@ -53,8 +51,7 @@ public class SocketAppender extends SocketAppenderBase<AccessEvent> { */ public SocketAppender(String host, int port) { this.port = port; - this.address = getAddressByName(host); - this.remoteHost = host; + this.host = host; } @Override diff --git a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java index 2b72e58..616a270 100644 --- a/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java +++ b/logback-classic/src/main/java/ch/qos/logback/classic/net/SocketAppender.java @@ -44,9 +44,7 @@ public class SocketAppender extends SocketAppenderBase<ILoggingEvent> { * 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; + this(address.getHostName(), port); } /** @@ -54,8 +52,7 @@ public class SocketAppender extends SocketAppenderBase<ILoggingEvent> { */ public SocketAppender(String host, int port) { this.port = port; - this.address = getAddressByName(host); - this.remoteHost = host; + this.host = host; } @Override diff --git a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java index 45cf3b9..aaecb2c 100644 --- a/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java +++ b/logback-classic/src/test/java/ch/qos/logback/classic/net/SocketAppenderTest.java @@ -209,7 +209,8 @@ public class SocketAppenderTest { @Test public void lateServerLaunch() throws InterruptedException { - socketAppender.setReconnectionDelay(20); + // FIXME + //socketAppender.setReconnectionDelay(20); configureClient(); Logger logger = lc.getLogger(Logger.ROOT_LOGGER_NAME); logger.debug("test msg"); diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedEventObjectInputStream.java similarity index 92% rename from logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java rename to logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedEventObjectInputStream.java index 5aa56f3..6edd818 100644 --- a/logback-core/src/main/java/ch/qos/logback/core/encoder/EventObjectInputStream.java +++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedEventObjectInputStream.java @@ -14,8 +14,8 @@ package ch.qos.logback.core.encoder; import static ch.qos.logback.core.CoreConstants.BYTES_PER_INT; -import static ch.qos.logback.core.encoder.ObjectStreamEncoder.START_PEBBLE; -import static ch.qos.logback.core.encoder.ObjectStreamEncoder.STOP_PEBBLE; +import static ch.qos.logback.core.encoder.BatchedObjectStreamEncoder.START_PEBBLE; +import static ch.qos.logback.core.encoder.BatchedObjectStreamEncoder.STOP_PEBBLE; import java.io.IOException; import java.io.InputStream; @@ -30,14 +30,14 @@ import java.util.List; * * @param <E> */ -public class EventObjectInputStream<E> extends InputStream { +public class BatchedEventObjectInputStream<E> extends InputStream { NonClosableInputStream ncis; List<E> buffer = new ArrayList<E>(); int index = 0; - EventObjectInputStream(InputStream is) throws IOException { + BatchedEventObjectInputStream(InputStream is) throws IOException { this.ncis = new NonClosableInputStream(is); } diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedObjectStreamEncoder.java similarity index 97% rename from logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java rename to logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedObjectStreamEncoder.java index c97c139..c7a1357 100644 --- a/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectStreamEncoder.java +++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/BatchedObjectStreamEncoder.java @@ -29,7 +29,7 @@ import ch.qos.logback.core.CoreConstants; * * @param <E> */ -public class ObjectStreamEncoder<E> extends EncoderBase<E> { +public class BatchedObjectStreamEncoder<E> extends EncoderBase<E> { static public int START_PEBBLE = 1853421169; //static public int START_PEBBLE = 1; diff --git a/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectOutputStreamEncoder.java b/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectOutputStreamEncoder.java new file mode 100644 index 0000000..3fa485d --- /dev/null +++ b/logback-core/src/main/java/ch/qos/logback/core/encoder/ObjectOutputStreamEncoder.java @@ -0,0 +1,48 @@ +/** + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2010, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under either + * the terms of the Eclipse Public License v1.0 as published by the Eclipse + * Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + */ +package ch.qos.logback.core.encoder; + +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.OutputStream; + +import ch.qos.logback.core.CoreConstants; + +public class ObjectOutputStreamEncoder<E> extends EncoderBase<E> { + + ObjectOutputStream oos; + protected int counter = 0; + + @Override + public void init(OutputStream os) throws IOException { + oos = new ObjectOutputStream(os); + } + + public void doEncode(E event) throws IOException { + oos.writeObject(event); + oos.flush(); + if (++counter >= CoreConstants.OOS_RESET_FREQUENCY) { + counter = 0; + // Failing to reset the object output stream every now and + // then creates a serious memory leak. + oos.reset(); + } + + } + + public void close() throws IOException { + oos.close(); + } + +} 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 475451a..008806d 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,7 +18,6 @@ import java.io.IOException; import java.io.ObjectOutputStream; import java.io.Serializable; import java.net.InetAddress; -import java.net.Socket; import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.CoreConstants; @@ -48,15 +47,12 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { * We remember host name as String in addition to the resolved InetAddress so * that it can be returned via getOption(). */ - protected String remoteHost; + protected String host; - protected InetAddress address; protected int port = DEFAULT_PORT; protected ObjectOutputStream oos; protected int reconnectionDelay = DEFAULT_RECONNECTION_DELAY; - private Connector connector; - protected int counter = 0; /** @@ -71,14 +67,14 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_port"); } - if (address == null) { + if (host == null) { errorCount++; addError("No remote address was configured for appender" + name + " For more information, please visit http://logback.qos.ch/codes.html#socket_no_host"); } - connect(address, port); + //connect(address, port); if (errorCount == 0) { this.started = true; @@ -114,31 +110,8 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<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 - } - addWarn(msg, e); - } - } @Override protected void append(E event) { @@ -146,12 +119,12 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { if (event == null) return; - if (address == null) { - addError("No remote host is set for SocketAppender named \"" - + this.name - + "\". For more information, please visit http://logback.qos.ch/codes.html#socket_no_host"); - return; - } +// if (address == null) { +// addError("No remote host is set for SocketAppender named \"" +// + this.name +// + "\". For more information, please visit http://logback.qos.ch/codes.html#socket_no_host"); +// return; +// } if (oos != null) { try { @@ -176,9 +149,6 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { oos = null; addWarn("Detected problem with connection: " + e); - if (reconnectionDelay > 0) { - fireConnector(); - } } } } @@ -186,15 +156,6 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { protected abstract void postProcessEvent(E event); protected abstract PreSerializationTransformer<E> getPST(); - void fireConnector() { - if (connector == null) { - addInfo("Starting a new connector thread."); - connector = new Connector(); - connector.setDaemon(true); - connector.setPriority(Thread.MIN_PRIORITY); - connector.start(); - } - } protected static InetAddress getAddressByName(String host) { try { @@ -210,15 +171,14 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { * name of the server where a {...@link SocketNode} is running. */ public void setRemoteHost(String host) { - address = getAddressByName(host); - remoteHost = host; + this.host = host; } /** * Returns value of the <b>RemoteHost</b> option. */ public String getRemoteHost() { - return remoteHost; + return host; } /** @@ -235,75 +195,6 @@ public abstract class SocketAppenderBase<E> extends AppenderBase<E> { 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; - } - - /** - * 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."); } - */ - } } diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java index 8cb9b6d..9eaefbf 100644 --- a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java +++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamBase.java @@ -15,26 +15,34 @@ package ch.qos.logback.core.recovery; import java.io.IOException; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; import ch.qos.logback.core.Context; +import ch.qos.logback.core.spi.ContextAware; +import ch.qos.logback.core.spi.ContextAwareImpl; import ch.qos.logback.core.status.ErrorStatus; import ch.qos.logback.core.status.InfoStatus; import ch.qos.logback.core.status.Status; import ch.qos.logback.core.status.StatusManager; -abstract public class ResilientOutputStreamBase extends OutputStream { +abstract public class ResilientOutputStreamBase extends OutputStream implements + ContextAware { final static int STATUS_COUNT_LIMIT = 2 * 4; private int noContextWarning = 0; private int statusCount = 0; - private Context context; private RecoveryCoordinator recoveryCoordinator; protected OutputStream os; protected boolean presumedClean = true; + private ContextAwareImpl cai = new ContextAwareImpl(this); + + List<ResilientOutputStreamListener> listenerList = new ArrayList<ResilientOutputStreamListener>(); + final private boolean isPresumedInError() { // existence of recoveryCoordinator indicates failed state return (recoveryCoordinator != null && !presumedClean); @@ -126,12 +134,23 @@ abstract public class ResilientOutputStreamBase extends OutputStream { try { os = openNewOutputStream(); presumedClean = true; + fireOutputStreamChangedEvent(); } catch (IOException e) { addStatusIfCountNotOverLimit(new ErrorStatus("Failed to open " + getDescription(), this, e)); } } + + void fireOutputStreamChangedEvent() { + for(ResilientOutputStreamListener listener: listenerList) { + listener.outputStreamChangedEvent(); + } + } + void addResilientOutputStreamListener(ResilientOutputStreamListener listener) { + listenerList.add(listener); + } + void addStatusIfCountNotOverLimit(Status s) { ++statusCount; if (statusCount < STATUS_COUNT_LIMIT) { @@ -146,23 +165,49 @@ abstract public class ResilientOutputStreamBase extends OutputStream { } public void addStatus(Status status) { - if (context == null) { + if (cai.getContext() == null) { if (noContextWarning++ == 0) { System.out.println("LOGBACK: No context given for " + this); } return; } - StatusManager sm = context.getStatusManager(); + + StatusManager sm = cai.getStatusManager(); if (sm != null) { sm.add(status); } } public Context getContext() { - return context; + return cai.getContext(); } public void setContext(Context context) { - this.context = context; + cai.setContext(context); + } + + public void addError(String msg) { + cai.addError(msg); + } + + public void addError(String msg, Throwable ex) { + cai.addError(msg, ex); + } + + public void addInfo(String msg) { + cai.addInfo(msg); + + } + + public void addInfo(String msg, Throwable ex) { + cai.addInfo(msg, ex); + } + + public void addWarn(String msg) { + cai.addWarn(msg); + } + + public void addWarn(String msg, Throwable ex) { + cai.addWarn(msg, ex); } } diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamListener.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamListener.java new file mode 100644 index 0000000..ba5b0b1 --- /dev/null +++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientOutputStreamListener.java @@ -0,0 +1,24 @@ +/** + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2010, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under either + * the terms of the Eclipse Public License v1.0 as published by the Eclipse + * Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + */ +package ch.qos.logback.core.recovery; + +public interface ResilientOutputStreamListener { + + /** + * ResilientOutputStream instance will fire this event each time the + * underlying output stream of the instance is changed. + */ + void outputStreamChangedEvent(); + +} diff --git a/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSocketStream.java b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSocketStream.java new file mode 100644 index 0000000..cf5a671 --- /dev/null +++ b/logback-core/src/main/java/ch/qos/logback/core/recovery/ResilientSocketStream.java @@ -0,0 +1,67 @@ +/** + * Logback: the reliable, generic, fast and flexible logging framework. + * Copyright (C) 1999-2010, QOS.ch. All rights reserved. + * + * This program and the accompanying materials are dual-licensed under either + * the terms of the Eclipse Public License v1.0 as published by the Eclipse + * Foundation + * + * or (per the licensee's choosing) + * + * under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + */ +package ch.qos.logback.core.recovery; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; + +import ch.qos.logback.core.Context; +import ch.qos.logback.core.spi.ContextAware; + +public class ResilientSocketStream extends ResilientOutputStreamBase implements ContextAware { + + String host; + int port; + Context context; + InetAddress inetAddress; + + public ResilientSocketStream(String host, int port) + throws IOException { + super(); + this.host = host; + this.port = port; + super.os = openNewOutputStream(); + this.presumedClean = true; + } + + protected InetAddress getAddressByName(String host) { + try { + return InetAddress.getByName(host); + } catch (Exception e) { + addError("Could not find address of [" + host + "].", e); + return null; + } + } + + + @Override + String getDescription() { + return "socket stream ["+host+":"+port+"]"; + } + + @Override + OutputStream openNewOutputStream() throws IOException { + Socket socket = new Socket(inetAddress, port); + return socket.getOutputStream(); + } + + @Override + public String toString() { + return "c.q.l.c.recovery.ResilientSocketStream@" + + System.identityHashCode(this); + } + +} diff --git a/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java b/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java index 42ac3c7..994ca2e 100644 --- a/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java +++ b/logback-core/src/test/java/ch/qos/logback/core/encoder/ObjectEncodeDecodeTest.java @@ -17,8 +17,8 @@ import ch.qos.logback.core.util.CoreTestConstants; public class ObjectEncodeDecodeTest { - ObjectStreamEncoder<String> encoder = new ObjectStreamEncoder<String>(); - EventObjectInputStream<String> eventStream; + BatchedObjectStreamEncoder<String> encoder = new BatchedObjectStreamEncoder<String>(); + BatchedEventObjectInputStream<String> eventStream; int diff = RandomUtil.getPositiveInt(); protected String randomOutputDir = CoreTestConstants.OUTPUT_DIR_PREFIX + diff @@ -43,7 +43,7 @@ public class ObjectEncodeDecodeTest { List<String> decodeList(File file) throws IOException { FileInputStream fis = new FileInputStream(file); - eventStream = new EventObjectInputStream<String>(fis); + eventStream = new BatchedEventObjectInputStream<String>(fis); List<String> back = new ArrayList<String>(); String e; while((e=eventStream.readEvent()) != null) { diff --git a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java index 4c6bc2f..5c42180 100644 --- a/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java +++ b/logback-examples/src/main/java/chapters/appenders/socket/SocketClient1.java @@ -51,7 +51,9 @@ public class SocketClient1 { SocketAppender socketAppender = new SocketAppender(); socketAppender.setRemoteHost(hostName); socketAppender.setPort(port); - socketAppender.setReconnectionDelay(10000); + + // FIXME + //socketAppender.setReconnectionDelay(10000); LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); socketAppender.setContext(lc); ----------------------------------------------------------------------- hooks/post-receive -- Logback: the generic, reliable, fast and flexible logging framework. _______________________________________________ logback-dev mailing list logback-dev@qos.ch http://qos.ch/mailman/listinfo/logback-dev