LOG4J2-228 & LOG4J2-246 - UDP now sends 1 event per packet. The data buffer is reset in a finally clause
git-svn-id: https://svn.apache.org/repos/asf/logging/log4j/log4j2/trunk@1487289 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java b/core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java
index 091dcb1..0ed1ce6 100644
--- a/core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/appender/DefaultErrorHandler.java
@@ -69,7 +69,7 @@
LOGGER.error(msg, t);
}
lastException = current;
- if (!appender.isExceptionSuppressed() && t != null) {
+ if (!appender.isExceptionSuppressed() && t != null && !(t instanceof AppenderRuntimeException)) {
throw new AppenderRuntimeException(msg, t);
}
}
@@ -87,7 +87,7 @@
LOGGER.error(msg, t);
}
lastException = current;
- if (!appender.isExceptionSuppressed() && t != null) {
+ if (!appender.isExceptionSuppressed() && t != null && !(t instanceof AppenderRuntimeException)) {
throw new AppenderRuntimeException(msg, t);
}
}
diff --git a/core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java b/core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
index 6dd56f7..f9d0665 100644
--- a/core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
@@ -98,7 +98,7 @@
@PluginAttr("advertise") final String advertise,
@PluginConfiguration final Configuration config) {
- final boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);
+ boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);
boolean isAdvertise = advertise == null ? false : Boolean.valueOf(advertise);
final boolean handleExceptions = suppress == null ? true : Boolean.valueOf(suppress);
final boolean fail = immediateFail == null ? true : Boolean.valueOf(immediateFail);
@@ -116,8 +116,12 @@
}
final String prot = protocol != null ? protocol : Protocol.TCP.name();
+ final Protocol p = EnglishEnums.valueOf(Protocol.class, protocol);
+ if (p.equals(Protocol.UDP)) {
+ isFlush = true;
+ }
- final AbstractSocketManager manager = createSocketManager(prot, host, port, reconnectDelay, fail, layout);
+ final AbstractSocketManager manager = createSocketManager(p, host, port, reconnectDelay, fail, layout);
if (manager == null) {
return null;
}
@@ -126,10 +130,9 @@
isAdvertise ? config.getAdvertiser() : null);
}
- protected static AbstractSocketManager createSocketManager(final String protocol, final String host, final int port,
+ protected static AbstractSocketManager createSocketManager(final Protocol p, final String host, final int port,
final int delay, final boolean immediateFail,
final Layout layout) {
- final Protocol p = EnglishEnums.valueOf(Protocol.class, protocol);
switch (p) {
case TCP:
return TCPSocketManager.getSocketManager(host, port, delay, immediateFail, layout);
diff --git a/core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java b/core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
index 55aff97..fe52f9d 100644
--- a/core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
@@ -29,6 +29,7 @@
import org.apache.logging.log4j.core.net.AbstractSocketManager;
import org.apache.logging.log4j.core.net.Advertiser;
import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.util.EnglishEnums;
import java.io.Serializable;
@@ -130,7 +131,8 @@
return null;
}
final String prot = protocol != null ? protocol : Protocol.UDP.name();
- final AbstractSocketManager manager = createSocketManager(prot, host, port, reconnectDelay, fail, layout);
+ final Protocol p = EnglishEnums.valueOf(Protocol.class, protocol);
+ final AbstractSocketManager manager = createSocketManager(p, host, port, reconnectDelay, fail, layout);
if (manager == null) {
return null;
}
diff --git a/core/src/main/java/org/apache/logging/log4j/core/net/DatagramOutputStream.java b/core/src/main/java/org/apache/logging/log4j/core/net/DatagramOutputStream.java
index 2fe3d9a..9846ee2 100644
--- a/core/src/main/java/org/apache/logging/log4j/core/net/DatagramOutputStream.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/net/DatagramOutputStream.java
@@ -48,13 +48,18 @@
private byte[] data;
+ private final byte[] header;
+ private final byte[] footer;
+
/**
* The Constructor.
* @param host The host to connect to.
* @param port The port on the host.
*/
- public DatagramOutputStream(final String host, final int port) {
+ public DatagramOutputStream(final String host, final int port, final byte[] header, final byte[] footer) {
this.port = port;
+ this.header = header;
+ this.footer = footer;
try {
address = InetAddress.getByName(host);
} catch (final UnknownHostException ex) {
@@ -89,11 +94,20 @@
@Override
public synchronized void flush() throws IOException {
- if (this.data != null && this.ds != null && this.address != null) {
- final DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
- ds.send(packet);
+ try {
+ if (this.data != null && this.ds != null && this.address != null) {
+ if (footer != null) {
+ copy(footer, 0, footer.length);
+ }
+ final DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
+ ds.send(packet);
+ }
+ } finally {
+ data = null;
+ if (header != null) {
+ copy(header, 0, header.length);
+ }
}
- data = null;
}
@Override
@@ -111,7 +125,7 @@
final int index = data == null ? 0 : data.length;
final byte[] copy = new byte[length + index];
if (data != null) {
- System.arraycopy(data, 0, copy, 0, index);
+ System.arraycopy(data, 0, copy, 0, data.length);
}
System.arraycopy(bytes, offset, copy, index, length);
data = copy;
diff --git a/core/src/main/java/org/apache/logging/log4j/core/net/DatagramSocketManager.java b/core/src/main/java/org/apache/logging/log4j/core/net/DatagramSocketManager.java
index 12b578c..633e758 100644
--- a/core/src/main/java/org/apache/logging/log4j/core/net/DatagramSocketManager.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/net/DatagramSocketManager.java
@@ -104,7 +104,8 @@
@Override
public DatagramSocketManager createManager(final String name, final FactoryData data) {
InetAddress address;
- final OutputStream os = new DatagramOutputStream(data.host, data.port);
+ final OutputStream os = new DatagramOutputStream(data.host, data.port, data.layout.getHeader(),
+ data.layout.getFooter());
try {
address = InetAddress.getByName(data.host);
} catch (final UnknownHostException ex) {
diff --git a/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServer.java b/core/src/main/java/org/apache/logging/log4j/core/net/UDPSocketServer.java
similarity index 73%
rename from core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServer.java
rename to core/src/main/java/org/apache/logging/log4j/core/net/UDPSocketServer.java
index 12d2ead..b7b946a 100644
--- a/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServer.java
+++ b/core/src/main/java/org/apache/logging/log4j/core/net/UDPSocketServer.java
@@ -57,14 +57,12 @@
private final DatagramSocket server;
- private final ConcurrentMap<Long, DatagramPacketHandler> handlers = new ConcurrentHashMap<Long, DatagramPacketHandler>();
-
// max size so we only have to deal with one packet
- private int maxBufferSize = 1024 * 65;
+ private int maxBufferSize = 1024 * 65 + 1024;
/**
* Constructor.
- *
+ *
* @param port
* to listen on.
* @throws IOException
@@ -80,7 +78,7 @@
/**
* Main startup for the server.
- *
+ *
* @param args
* The command line arguments.
* @throws Exception
@@ -138,63 +136,19 @@
byte[] buf = new byte[maxBufferSize];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
server.receive(packet);
- final DatagramPacketHandler handler = new DatagramPacketHandler(packet);
- handlers.put(handler.getId(), handler);
- handler.start();
- } catch (final IOException ioe) {
- System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
- ioe.printStackTrace();
- }
- }
- for (final Map.Entry<Long, DatagramPacketHandler> entry : handlers.entrySet()) {
- final DatagramPacketHandler handler = entry.getValue();
- handler.shutdown();
- try {
- handler.join();
- } catch (final InterruptedException ie) {
- // Ignore the exception
- }
- }
- }
-
- /**
- * Thread that processes the events.
- */
- private class DatagramPacketHandler extends Thread {
- private final ObjectInputStream ois;
- private boolean shutdown = false;
-
- public DatagramPacketHandler(final DatagramPacket packet) throws IOException {
- this.ois = new ObjectInputStream(new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength()));
- }
-
- public void shutdown() {
- this.shutdown = true;
- interrupt();
- }
-
- @Override
- public void run() {
- boolean closed = false;
- try {
- try {
- while (!shutdown) {
- final LogEvent event = (LogEvent) ois.readObject();
- if (event != null) {
- log(event);
- }
- }
- } catch (final EOFException eof) {
- closed = true;
- } catch (final OptionalDataException opt) {
- logger.error("OptionalDataException eof=" + opt.eof + " length=" + opt.length, opt);
- } catch (final ClassNotFoundException cnfe) {
- logger.error("Unable to locate LogEvent class", cnfe);
- } catch (final IOException ioe) {
- logger.error("IOException encountered while reading from socket", ioe);
+ ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(packet.getData(), packet.getOffset(), packet.getLength()));
+ final LogEvent event = (LogEvent) ois.readObject();
+ if (event != null) {
+ log(event);
}
- } finally {
- handlers.remove(getId());
+ } catch (final OptionalDataException opt) {
+ logger.error("OptionalDataException eof=" + opt.eof + " length=" + opt.length, opt);
+ } catch (final ClassNotFoundException cnfe) {
+ logger.error("Unable to locate LogEvent class", cnfe);
+ } catch (final EOFException eofe) {
+ logger.info("EOF encountered");
+ } catch (final IOException ioe) {
+ logger.error("Exception encountered on accept. Ignoring. Stack Trace :", ioe);
}
}
}
diff --git a/core/src/test/java/org/apache/logging/log4j/core/net/AbstractSocketServerTest.java b/core/src/test/java/org/apache/logging/log4j/core/net/AbstractSocketServerTest.java
index 507b4ef..22f47b2 100644
--- a/core/src/test/java/org/apache/logging/log4j/core/net/AbstractSocketServerTest.java
+++ b/core/src/test/java/org/apache/logging/log4j/core/net/AbstractSocketServerTest.java
@@ -23,6 +23,7 @@
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AppenderRuntimeException;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.SocketAppender;
import org.apache.logging.log4j.core.filter.AbstractFilter;
@@ -31,6 +32,7 @@
import org.junit.After;
import org.junit.Test;
+import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
@@ -63,12 +65,14 @@
private final String port;
private final String protocol;
+ private final boolean expectLengthException;
private final Logger root = ctx.getLogger(AbstractSocketServerTest.class.getSimpleName());
- protected AbstractSocketServerTest(final String protocol, final String port) {
+ protected AbstractSocketServerTest(final String protocol, final String port, final boolean expectLengthException) {
this.protocol = protocol;
this.port = port;
+ this.expectLengthException = expectLengthException;
}
@After
@@ -87,20 +91,30 @@
Arrays.fill(a64K, 'a');
final String m1 = new String(a64K);
final String m2 = MESSAGE_2 + m1;
- testServer(m1, m2);
+ if (expectLengthException) {
+ try {
+ testServer(m1, m2);
+
+ } catch (AppenderRuntimeException are) {
+ assertTrue("", are.getCause() != null && are.getCause() instanceof IOException);
+ // Failure expected.
+ }
+ } else {
+ testServer(m1, m2);
+ }
}
protected void testServer(final String message1, final String message2) throws Exception {
final Filter socketFilter = new ThreadFilter(Filter.Result.NEUTRAL, Filter.Result.DENY);
final Filter serverFilter = new ThreadFilter(Filter.Result.DENY, Filter.Result.NEUTRAL);
final SocketAppender<Serializable> appender = SocketAppender.createAppender("localhost", this.port, this.protocol, "-1", null, "Test", null,
- null, null, socketFilter, null, null);
+ "false", null, socketFilter, null, null);
appender.start();
final ListAppender<LogEvent> listApp = new ListAppender<LogEvent>("Events", serverFilter, null, false, false);
listApp.start();
final PatternLayout layout = PatternLayout.createLayout("%m %ex%n", null, null, null, null);
final ConsoleAppender<String> console = ConsoleAppender.createAppender(layout, null, "SYSTEM_OUT", "Console", "false", "true");
- final Logger serverLogger = ctx.getLogger(SocketServer.class.getName());
+ final Logger serverLogger = ctx.getLogger(this.getClass().getName());
serverLogger.addAppender(console);
serverLogger.setAdditive(false);
diff --git a/core/src/test/java/org/apache/logging/log4j/core/net/TCPSocketServerTest.java b/core/src/test/java/org/apache/logging/log4j/core/net/TCPSocketServerTest.java
index 62241bb..5075dd0 100644
--- a/core/src/test/java/org/apache/logging/log4j/core/net/TCPSocketServerTest.java
+++ b/core/src/test/java/org/apache/logging/log4j/core/net/TCPSocketServerTest.java
@@ -47,7 +47,7 @@
}
public TCPSocketServerTest() {
- super("tcp", PORT);
+ super("tcp", PORT, false);
}
}
diff --git a/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServerTest.java b/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServerTest.java
index 2eddc99..5e83681 100644
--- a/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServerTest.java
+++ b/core/src/test/java/org/apache/logging/log4j/core/net/UDPSocketServerTest.java
@@ -22,7 +22,6 @@
import org.junit.BeforeClass;
import org.junit.Ignore;
-@Ignore
public class UDPSocketServerTest extends AbstractSocketServerTest {
private static final String PORT = "8199";
private static final int PORT_NUM = Integer.parseInt(PORT);
@@ -49,7 +48,7 @@
}
public UDPSocketServerTest() {
- super("udp", PORT);
+ super("udp", PORT, true);
}
}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 037d029..f22e301 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -22,6 +22,12 @@
</properties>
<body>
<release version="2.0-beta7" date="2013-??-??" description="Bug fixes and enhancements">
+ <action issue="LOG4J2-246" dev="rgoers" type="fix">
+ Data buffer is reset in finally clause.
+ </action>
+ <action issue="LOG4J2-228" dev="rgoers" type="fix">
+ UDP now sends one event per packet.
+ </action>
<action dev="rpopma" type="update">
Method name changes in interface org.apache.logging.log4j.spi.ThreadContextMap:
getContext() to getCopy(), get() to getImmutableMapOrNull().