You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2012/12/01 19:49:51 UTC
svn commit: r1416041 - in /logging/log4j/log4j2/trunk:
core/src/main/java/org/apache/logging/log4j/core/
core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/
core/src/main/java/org/apache/logging/log4j/core/net/
core/src/test/java/org/apa...
Author: rgoers
Date: Sat Dec 1 18:49:48 2012
New Revision: 1416041
URL: http://svn.apache.org/viewvc?rev=1416041&view=rev
Log:
LOG4J2-126 - Allow JMS appenders to recover if the queue or topic is unavailable.
Added:
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueFailoverTest.java
- copied, changed from r1411553, logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueAppenderTest.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSTopicFailoverTest.java
logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmsqueue-failover.xml
- copied, changed from r1411345, logging/log4j/log4j2/trunk/core/src/test/resources/log4j-failover.xml
logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmstopic-failover.xml
Modified:
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/AbstractServer.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/AbstractJMSManager.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSQueueManager.java
logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSTopicManager.java
logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/SocketServerTest.java
logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java
logging/log4j/log4j2/trunk/src/changes/changes.xml
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/AbstractServer.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/AbstractServer.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/AbstractServer.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/AbstractServer.java Sat Dec 1 18:49:48 2012
@@ -26,7 +26,7 @@ public class AbstractServer {
private final LoggerContext context;
protected AbstractServer() {
- context = (LoggerContext) LogManager.getContext();
+ context = (LoggerContext) LogManager.getContext(false);
}
protected void log(LogEvent event) {
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/appender/rewrite/PropertiesRewritePolicy.java Sat Dec 1 18:49:48 2012
@@ -65,10 +65,8 @@ public final class PropertiesRewritePoli
Map<String, String> props = new HashMap<String, String>(source.getContextMap());
for (Map.Entry<Property, Boolean> entry : properties.entrySet()) {
Property prop = entry.getKey();
- if (!props.containsKey(prop.getName())) {
- props.put(prop.getName(), entry.getValue() ?
- config.getSubst().replace(prop.getValue()) : prop.getValue());
- }
+ props.put(prop.getName(), entry.getValue() ?
+ config.getSubst().replace(prop.getValue()) : prop.getValue());
}
return new Log4jLogEvent(source.getLoggerName(), source.getMarker(), source.getFQCN(), source.getLevel(),
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/AbstractJMSManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/AbstractJMSManager.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/AbstractJMSManager.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/AbstractJMSManager.java Sat Dec 1 18:49:48 2012
@@ -75,7 +75,7 @@ public abstract class AbstractJMSManager
try {
return ctx.lookup(name);
} catch (NameNotFoundException e) {
- LOGGER.error("Could not find name [" + name + "].");
+ LOGGER.warn("Could not find name [" + name + "].");
throw e;
}
}
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSQueueManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSQueueManager.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSQueueManager.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSQueueManager.java Sat Dec 1 18:49:48 2012
@@ -36,22 +36,32 @@ public class JMSQueueManager extends Abs
private static final JMSQueueManagerFactory factory = new JMSQueueManagerFactory();
- private final QueueConnection queueConnection;
- private final QueueSession queueSession;
- private final QueueSender queueSender;
+ private QueueInfo info;
+ private final String factoryBindingName;
+ private final String queueBindingName;
+ private final String userName;
+ private final String password;
+ private final Context context;
/**
* The Constructor.
* @param name The unique name of the connection.
- * @param conn The QueueConnection.
- * @param sess The QueueSession.
- * @param sender The QueueSender.
+ * @param context The context.
+ * @param factoryBindingName The factory binding name.
+ * @param queueBindingName The queue binding name.
+ * @param userName The user name.
+ * @param password The credentials for the user.
+ * @param info The Queue connection info.
*/
- protected JMSQueueManager(String name, QueueConnection conn, QueueSession sess, QueueSender sender) {
+ protected JMSQueueManager(String name, Context context, String factoryBindingName, String queueBindingName,
+ String userName, String password, QueueInfo info) {
super(name);
- this.queueConnection = conn;
- this.queueSession = sess;
- this.queueSender = sender;
+ this.context = context;
+ this.factoryBindingName = factoryBindingName;
+ this.queueBindingName = queueBindingName;
+ this.userName = userName;
+ this.password = password;
+ this.info = info;
}
/**
@@ -88,21 +98,24 @@ public class JMSQueueManager extends Abs
}
@Override
- public void send(Serializable object) throws Exception {
- super.send(object, queueSession, queueSender);
+ public synchronized void send(Serializable object) throws Exception {
+ if (info == null) {
+ info = connect(context, factoryBindingName, queueBindingName, userName, password, false);
+ }
+ super.send(object, info.session, info.sender);
}
@Override
public void releaseSub() {
try {
- if (queueSession != null) {
- queueSession.close();
- }
- if (queueConnection != null) {
- queueConnection.close();
+ if (info != null) {
+ info.session.close();
+ info.conn.close();
}
} catch (JMSException ex) {
LOGGER.error("Error closing " + getName(), ex);
+ } finally {
+ info = null;
}
}
@@ -135,6 +148,47 @@ public class JMSQueueManager extends Abs
}
}
+ private static QueueInfo connect(Context context, String factoryBindingName, String queueBindingName,
+ String userName, String password, boolean suppress) throws Exception {
+ try {
+ QueueConnectionFactory factory = (QueueConnectionFactory) lookup(context, factoryBindingName);
+ QueueConnection conn;
+ if (userName != null) {
+ conn = factory.createQueueConnection(userName, password);
+ } else {
+ conn = factory.createQueueConnection();
+ }
+ QueueSession sess = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+ Queue queue = (Queue) lookup(context, queueBindingName);
+ QueueSender sender = sess.createSender(queue);
+ conn.start();
+ return new QueueInfo(conn, sess, sender);
+ } catch (NamingException ex) {
+ LOGGER.warn("Unable to locate connection factory " + factoryBindingName, ex);
+ if (!suppress) {
+ throw ex;
+ }
+ } catch (JMSException ex) {
+ LOGGER.warn("Unable to create connection to queue " + queueBindingName, ex);
+ if (!suppress) {
+ throw ex;
+ }
+ }
+ return null;
+ }
+
+ private static class QueueInfo {
+ private final QueueConnection conn;
+ private final QueueSession session;
+ private final QueueSender sender;
+
+ public QueueInfo(QueueConnection conn, QueueSession session, QueueSender sender) {
+ this.conn = conn;
+ this.session = session;
+ this.sender = sender;
+ }
+ }
+
/**
* Factory to create the JMSQueueManager.
*/
@@ -144,23 +198,14 @@ public class JMSQueueManager extends Abs
try {
Context ctx = createContext(data.factoryName, data.providerURL, data.urlPkgPrefixes,
data.securityPrincipalName, data.securityCredentials);
- QueueConnectionFactory factory = (QueueConnectionFactory) lookup(ctx, data.factoryBindingName);
- QueueConnection conn;
- if (data.userName != null) {
- conn = factory.createQueueConnection(data.userName, data.password);
- } else {
- conn = factory.createQueueConnection();
- }
- QueueSession sess = conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
- Queue queue = (Queue) lookup(ctx, data.queueBindingName);
- QueueSender sender = sess.createSender(queue);
- conn.start();
- return new JMSQueueManager(name, conn, sess, sender);
-
+ QueueInfo info = connect(ctx, data.factoryBindingName, data.queueBindingName, data.userName,
+ data.password, true);
+ return new JMSQueueManager(name, ctx, data.factoryBindingName, data.queueBindingName,
+ data.userName, data.password, info);
} catch (NamingException ex) {
LOGGER.error("Unable to locate resource", ex);
- } catch (JMSException jmsex) {
- LOGGER.error("Unable to establish connection", jmsex);
+ } catch (Exception ex) {
+ LOGGER.error("Unable to connect", ex);
}
return null;
Modified: logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSTopicManager.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSTopicManager.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSTopicManager.java (original)
+++ logging/log4j/log4j2/trunk/core/src/main/java/org/apache/logging/log4j/core/net/JMSTopicManager.java Sat Dec 1 18:49:48 2012
@@ -36,22 +36,31 @@ public class JMSTopicManager extends Abs
private static final JMSTopicManagerFactory factory = new JMSTopicManagerFactory();
- private final TopicConnection topicConnection;
- private final TopicSession topicSession;
- private final TopicPublisher topicPublisher;
-
+ private TopicInfo info;
+ private final String factoryBindingName;
+ private final String topicBindingName;
+ private final String userName;
+ private final String password;
+ private final Context context;
/**
* Constructor.
* @param name The unique name of the connection.
- * @param conn The TopicConnection.
- * @param sess The TopicSession.
- * @param pub The TopicPublisher.
+ * @param context The context.
+ * @param factoryBindingName The factory binding name.
+ * @param topicBindingName The queue binding name.
+ * @param userName The user name.
+ * @param password The credentials for the user.
+ * @param info The Queue connection info.
*/
- public JMSTopicManager(String name, TopicConnection conn, TopicSession sess, TopicPublisher pub) {
+ protected JMSTopicManager(String name, Context context, String factoryBindingName, String topicBindingName,
+ String userName, String password, TopicInfo info) {
super(name);
- this.topicConnection = conn;
- this.topicSession = sess;
- this.topicPublisher = pub;
+ this.context = context;
+ this.factoryBindingName = factoryBindingName;
+ this.topicBindingName = topicBindingName;
+ this.userName = userName;
+ this.password = password;
+ this.info = info;
}
/**
@@ -90,17 +99,18 @@ public class JMSTopicManager extends Abs
@Override
public void send(Serializable object) throws Exception {
- super.send(object, topicSession, topicPublisher);
+ if (info == null) {
+ info = connect(context, factoryBindingName, topicBindingName, userName, password, false);
+ }
+ super.send(object, info.session, info.publisher);
}
@Override
public void releaseSub() {
try {
- if (topicSession != null) {
- topicSession.close();
- }
- if (topicConnection != null) {
- topicConnection.close();
+ if (info != null) {
+ info.session.close();
+ info.conn.close();
}
} catch (JMSException ex) {
LOGGER.error("Error closing " + getName(), ex);
@@ -136,31 +146,64 @@ public class JMSTopicManager extends Abs
}
}
+ private static TopicInfo connect(Context context, String factoryBindingName, String queueBindingName,
+ String userName, String password, boolean suppress) throws Exception {
+ try {
+ TopicConnectionFactory factory = (TopicConnectionFactory) lookup(context, factoryBindingName);
+ TopicConnection conn;
+ if (userName != null) {
+ conn = factory.createTopicConnection(userName, password);
+ } else {
+ conn = factory.createTopicConnection();
+ }
+ TopicSession sess = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
+ Topic topic = (Topic) lookup(context, queueBindingName);
+ TopicPublisher publisher = sess.createPublisher(topic);
+ conn.start();
+ return new TopicInfo(conn, sess, publisher);
+ } catch (NamingException ex) {
+ LOGGER.warn("Unable to locate connection factory " + factoryBindingName, ex);
+ if (!suppress) {
+ throw ex;
+ }
+ } catch (JMSException ex) {
+ LOGGER.warn("Unable to create connection to queue " + queueBindingName, ex);
+ if (!suppress) {
+ throw ex;
+ }
+ }
+ return null;
+ }
+
+ private static class TopicInfo {
+ private final TopicConnection conn;
+ private final TopicSession session;
+ private final TopicPublisher publisher;
+
+ public TopicInfo(TopicConnection conn, TopicSession session, TopicPublisher publisher) {
+ this.conn = conn;
+ this.session = session;
+ this.publisher = publisher;
+ }
+ }
+
/**
- * Factory to create a JMSTopicManager.
+ * Factory to create the JMSQueueManager.
*/
private static class JMSTopicManagerFactory implements ManagerFactory<JMSTopicManager, FactoryData> {
public JMSTopicManager createManager(String name, FactoryData data) {
try {
Context ctx = createContext(data.factoryName, data.providerURL, data.urlPkgPrefixes,
- data.securityPrincipalName, data.securityCredentials);
- TopicConnectionFactory factory = (TopicConnectionFactory) lookup(ctx, data.factoryBindingName);
- TopicConnection conn;
- if (data.userName != null) {
- conn = factory.createTopicConnection(data.userName, data.password);
- } else {
- conn = factory.createTopicConnection();
- }
- TopicSession sess = conn.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
- Topic topic = (Topic) lookup(ctx, data.topicBindingName);
- TopicPublisher pub = sess.createPublisher(topic);
- conn.start();
- return new JMSTopicManager(name, conn, sess, pub);
+ data.securityPrincipalName, data.securityCredentials);
+ TopicInfo info = connect(ctx, data.factoryBindingName, data.topicBindingName, data.userName,
+ data.password, true);
+ return new JMSTopicManager(name, ctx, data.factoryBindingName, data.topicBindingName,
+ data.userName, data.password, info);
} catch (NamingException ex) {
- LOGGER.error("Bad Name " + data.topicBindingName, ex);
- } catch (JMSException jmsex) {
- LOGGER.error("Unable to create publisher ", jmsex);
+ LOGGER.error("Unable to locate resource", ex);
+ } catch (Exception ex) {
+ LOGGER.error("Unable to connect", ex);
}
return null;
Copied: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueFailoverTest.java (from r1411553, logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueAppenderTest.java)
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueFailoverTest.java?p2=logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueFailoverTest.java&p1=logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueAppenderTest.java&r1=1411553&r2=1416041&rev=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueAppenderTest.java (original)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSQueueFailoverTest.java Sat Dec 1 18:49:48 2012
@@ -18,28 +18,20 @@ package org.apache.logging.log4j.core.ne
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.Appender;
-import org.apache.logging.log4j.core.Filter;
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.ConsoleAppender;
-import org.apache.logging.log4j.core.appender.JMSQueueAppender;
import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.XMLConfigurationFactory;
-import org.apache.logging.log4j.test.appender.ListAppender;
-import org.apache.logging.log4j.core.filter.CompositeFilter;
-import org.apache.logging.log4j.core.filter.AbstractFilter;
-import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.status.StatusConsoleListener;
import org.apache.logging.log4j.status.StatusLogger;
-
-import org.junit.After;
+import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.AfterClass;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-
import org.mockejb.jms.MockQueue;
import org.mockejb.jms.QueueConnectionFactoryImpl;
import org.mockejb.jndi.MockContextFactory;
@@ -55,42 +47,81 @@ import static org.junit.Assert.assertTru
/**
*
*/
-public class JMSQueueAppenderTest {
+public class JMSQueueFailoverTest {
- private static final String FACTORY_NAME = "TestQueueConnectionFactory";
- private static final String QUEUE_NAME = "TestQueue";
+ private static final String FACTORY_NAME = "QueueConnectionFactory";
+ private static final String QUEUE_NAME = "Log4j2Queue";
private static Context context;
private static AbstractJMSReceiver receiver;
- private static final String CONFIG = "log4j-jmsqueue.xml";
+ private static final String CONFIG = "log4j-jmsqueue-failover.xml";
- LoggerContext ctx = (LoggerContext) LogManager.getContext();
- Logger root = ctx.getLogger("JMSQueueTest");
+ private static Configuration config;
+ private static ListAppender app;
+ private static LoggerContext ctx;
@BeforeClass
public static void setupClass() throws Exception {
+ setupQueue();
+ System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ ctx = (LoggerContext) LogManager.getContext(false);
+ }
+
+ @AfterClass
+ public static void cleanupClass() {
+ System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+ ctx.reconfigure();
+ StatusLogger.getLogger().reset();
+ }
+
+ @Before
+ public void before() {
+ config = ctx.getConfiguration();
+ for (Map.Entry<String, Appender> entry : config.getAppenders().entrySet()) {
+ if (entry.getKey().equals("List")) {
+ app = (ListAppender) entry.getValue();
+ break;
+ }
+ }
+ assertNotNull("No Appender", app);
+ app.clear();
+ ThreadContext.clear();
+ }
+
+ private static void setupQueue() throws Exception {
// MockContextFactory becomes the primary JNDI provider
StatusConsoleListener l = new StatusConsoleListener(Level.ERROR);
StatusLogger.getLogger().registerListener(l);
MockContextFactory.setAsInitial();
context = new InitialContext();
context.rebind(FACTORY_NAME, new QueueConnectionFactoryImpl() );
- context.rebind(QUEUE_NAME, new MockQueue(QUEUE_NAME));
- System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
- receiver = new JMSQueueReceiver(FACTORY_NAME, QUEUE_NAME, null, null);
+ //context.rebind(QUEUE_NAME, new MockQueue(QUEUE_NAME));
+ //System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ //receiver = new JMSQueueReceiver(FACTORY_NAME, QUEUE_NAME, null, null);
}
- @AfterClass
- public static void cleanupClass() {
- StatusLogger.getLogger().reset();
+ @Test
+ public void testFailover() throws Exception {
+ ThreadContext.put("appender", "Failover");
+ Logger logger = LogManager.getLogger(JMSQueueFailoverTest.class);
+ logger.debug("Test Message");
+ List<LogEvent> events = app.getEvents();
+ assertNotNull("No events returned", events);
+ assertTrue("No events returned", events.size() > 0);
+ assertTrue("Incorrect event", "Test Message".equals(events.get(0).getMessage().getFormattedMessage()));
}
@Test
- public void testConfiguration() throws Exception {
- LoggerContext ctx = (LoggerContext) LogManager.getContext();
- Configuration config = ctx.getConfiguration();
- Map<String, Appender> appenders = config.getAppenders();
- assertTrue(appenders.containsKey("JMSQueue"));
+ public void testReconnect() throws Exception {
+ context.rebind(QUEUE_NAME, new MockQueue(QUEUE_NAME));
+ receiver = new JMSQueueReceiver(FACTORY_NAME, QUEUE_NAME, null, null);
+ ThreadContext.put("appender", "Failover");
+ Logger logger = LogManager.getLogger(JMSQueueFailoverTest.class);
+ logger.debug("Test Message");
+ List<LogEvent> events = app.getEvents();
+ assertNotNull("No events returned", events);
+ assertTrue("No events returned", events.size() > 0);
+ assertTrue("Incorrect event", "Test Message".equals(events.get(0).getMessage().getFormattedMessage()));
}
}
Added: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSTopicFailoverTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSTopicFailoverTest.java?rev=1416041&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSTopicFailoverTest.java (added)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/JMSTopicFailoverTest.java Sat Dec 1 18:49:48 2012
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.net;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.XMLConfigurationFactory;
+import org.apache.logging.log4j.status.StatusConsoleListener;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.test.appender.ListAppender;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockejb.jms.MockTopic;
+import org.mockejb.jms.TopicConnectionFactoryImpl;
+import org.mockejb.jndi.MockContextFactory;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class JMSTopicFailoverTest {
+
+ private static final String FACTORY_NAME = "TopicConnectionFactory";
+ private static final String TOPIC_NAME = "Log4j2Topic";
+
+ private static Context context;
+
+ private static final String CONFIG = "log4j-jmstopic-failover.xml";
+
+ private static Configuration config;
+ private static ListAppender app;
+ private static LoggerContext ctx;
+
+ @BeforeClass
+ public static void setupClass() throws Exception {
+ setupQueue();
+ System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ ctx = (LoggerContext) LogManager.getContext(false);
+ }
+
+ @AfterClass
+ public static void cleanupClass() {
+ System.clearProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY);
+ ctx.reconfigure();
+ StatusLogger.getLogger().reset();
+ }
+
+ @Before
+ public void before() {
+ config = ctx.getConfiguration();
+ for (Map.Entry<String, Appender> entry : config.getAppenders().entrySet()) {
+ if (entry.getKey().equals("List")) {
+ app = (ListAppender) entry.getValue();
+ break;
+ }
+ }
+ assertNotNull("No Appender", app);
+ app.clear();
+ ThreadContext.clear();
+ }
+
+ private static void setupQueue() throws Exception {
+ // MockContextFactory becomes the primary JNDI provider
+ StatusConsoleListener l = new StatusConsoleListener(Level.ERROR);
+ StatusLogger.getLogger().registerListener(l);
+ MockContextFactory.setAsInitial();
+ context = new InitialContext();
+ context.rebind(FACTORY_NAME, new TopicConnectionFactoryImpl() );
+ //context.rebind(QUEUE_NAME, new MockQueue(QUEUE_NAME));
+ //System.setProperty(XMLConfigurationFactory.CONFIGURATION_FILE_PROPERTY, CONFIG);
+ //receiver = new JMSQueueReceiver(FACTORY_NAME, QUEUE_NAME, null, null);
+ }
+
+ @Test
+ public void testFailover() throws Exception {
+ ThreadContext.put("appender", "Failover");
+ Logger logger = LogManager.getLogger(JMSTopicFailoverTest.class);
+ logger.debug("Test Message");
+ List<LogEvent> events = app.getEvents();
+ assertNotNull("No events returned", events);
+ assertTrue("No events returned", events.size() > 0);
+ assertTrue("Incorrect event", "Test Message".equals(events.get(0).getMessage().getFormattedMessage()));
+ }
+
+ @Test
+ public void testReconnect() throws Exception {
+ context.rebind(TOPIC_NAME, new MockTopic(TOPIC_NAME));
+ AbstractJMSReceiver receiver = new JMSTopicReceiver(FACTORY_NAME, TOPIC_NAME, null, null);
+ ThreadContext.put("appender", "Failover");
+ Logger logger = LogManager.getLogger(JMSTopicFailoverTest.class);
+ logger.debug("Test Message");
+ List<LogEvent> events = app.getEvents();
+ assertNotNull("No events returned", events);
+ assertTrue("No events returned", events.size() > 0);
+ assertTrue("Incorrect event", "Test Message".equals(events.get(0).getMessage().getFormattedMessage()));
+ }
+}
Modified: logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/SocketServerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/SocketServerTest.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/SocketServerTest.java (original)
+++ logging/log4j/log4j2/trunk/core/src/test/java/org/apache/logging/log4j/core/net/SocketServerTest.java Sat Dec 1 18:49:48 2012
@@ -55,12 +55,12 @@ public class SocketServerTest {
private static SocketServer tcp;
private static Thread thread;
- LoggerContext ctx = (LoggerContext) LogManager.getContext();
+ LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Logger root = ctx.getLogger("SocketServerTest");
@BeforeClass
public static void setupClass() throws Exception {
- ((LoggerContext) LogManager.getContext()).reconfigure();
+ ((LoggerContext) LogManager.getContext(false)).reconfigure();
tcp = new SocketServer(PORTNUM);
thread = new Thread(tcp);
thread.start();
Copied: logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmsqueue-failover.xml (from r1411345, logging/log4j/log4j2/trunk/core/src/test/resources/log4j-failover.xml)
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmsqueue-failover.xml?p2=logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmsqueue-failover.xml&p1=logging/log4j/log4j2/trunk/core/src/test/resources/log4j-failover.xml&r1=1411345&r2=1416041&rev=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j-failover.xml (original)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmsqueue-failover.xml Sat Dec 1 18:49:48 2012
@@ -18,9 +18,16 @@
-->
<configuration status="error" name="FailoverTest" packages="org.apache.logging.log4j.test">
<Appenders>
- <AlwaysFail name="Fail" />
- <List name="List" />
- <Failover name="Failover" primary="Fail" suppressExceptions="false">
+ <List name="List"/>
+ <JMSQueue name="Log4j2Queue" queueBindingName="Log4j2Queue" factoryBindingName="QueueConnectionFactory"
+ suppressExceptions="false"/>
+ <Rewrite name="Rewrite" suppressExceptions="false">
+ <PropertiesRewritePolicy>
+ <Property name="appender">List</Property>
+ </PropertiesRewritePolicy>
+ <appender-ref ref="Log4j2Queue"/>
+ </Rewrite>
+ <Failover name="Failover" primary="Rewrite" suppressExceptions="false">
<Failovers>
<appender-ref ref="List"/>
</Failovers>
@@ -28,8 +35,17 @@
</Appenders>
<loggers>
- <root level="error">
- <appender-ref ref="Failover"/>
+ <root level="debug">
+ <appender-ref ref="Failover">
+ <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
+ <KeyValuePair key="appender" value="Failover"/>
+ </ThreadContextMapFilter>
+ </appender-ref>
+ <appender-ref ref="List">
+ <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
+ <KeyValuePair key="appender" value="List"/>
+ </ThreadContextMapFilter>
+ </appender-ref>
</root>
</loggers>
Added: logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmstopic-failover.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmstopic-failover.xml?rev=1416041&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmstopic-failover.xml (added)
+++ logging/log4j/log4j2/trunk/core/src/test/resources/log4j-jmstopic-failover.xml Sat Dec 1 18:49:48 2012
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<configuration status="error" name="FailoverTest" packages="org.apache.logging.log4j.test">
+ <Appenders>
+ <List name="List"/>
+ <JMSTopic name="Log4j2Topic" topicBindingName="Log4j2Topic" factoryBindingName="TopicConnectionFactory"
+ suppressExceptions="false"/>
+ <Rewrite name="Rewrite" suppressExceptions="false">
+ <PropertiesRewritePolicy>
+ <Property name="appender">List</Property>
+ </PropertiesRewritePolicy>
+ <appender-ref ref="Log4j2Topic"/>
+ </Rewrite>
+ <Failover name="Failover" primary="Rewrite" suppressExceptions="false">
+ <Failovers>
+ <appender-ref ref="List"/>
+ </Failovers>
+ </Failover>
+ </Appenders>
+
+ <loggers>
+ <root level="debug">
+ <appender-ref ref="Failover">
+ <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
+ <KeyValuePair key="appender" value="Failover"/>
+ </ThreadContextMapFilter>
+ </appender-ref>
+ <appender-ref ref="List">
+ <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY">
+ <KeyValuePair key="appender" value="List"/>
+ </ThreadContextMapFilter>
+ </appender-ref>
+ </root>
+ </loggers>
+
+</configuration>
\ No newline at end of file
Modified: logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java (original)
+++ logging/log4j/log4j2/trunk/flume-ng/src/main/java/org/apache/logging/log4j/flume/appender/FlumeEvent.java Sat Dec 1 18:49:48 2012
@@ -30,6 +30,7 @@ import org.apache.logging.log4j.message.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -86,6 +87,7 @@ public class FlumeEvent extends SimpleEv
String[] array = includes.split(",");
if (array.length > 0) {
for (String str : array) {
+ str = str.trim();
if (mdc.containsKey(str)) {
ctx.put(str, mdc.get(str));
}
@@ -94,7 +96,10 @@ public class FlumeEvent extends SimpleEv
} else if (excludes != null) {
String[] array = excludes.split(",");
if (array.length > 0) {
- List<String> list = Arrays.asList(array);
+ List<String> list = new ArrayList<String>(array.length);
+ for (String value : array) {
+ list.add(value.trim());
+ }
for (Map.Entry<String, String> entry : mdc.entrySet()) {
if (!list.contains(entry.getKey())) {
ctx.put(entry.getKey(), entry.getValue());
@@ -109,6 +114,7 @@ public class FlumeEvent extends SimpleEv
String[] array = required.split(",");
if (array.length > 0) {
for (String str : array) {
+ str = str.trim();
if (!mdc.containsKey(str)) {
throw new LoggingException("Required key " + str + " is missing from the MDC");
}
Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1416041&r1=1416040&r2=1416041&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Sat Dec 1 18:49:48 2012
@@ -23,6 +23,9 @@
<body>
<release version="2.0-beta4" date="TBD" description="Bug fixes and enhancements">
+ <action issue="LOG4J2-126" dev="rgoers" type="fix">
+ Allow JMS appenders to recover if the queue or topic is unavailable.
+ </action>
<action issue="LOG4J2-128" dev="rgoers" type="update">
Add follow attribute to Console Appender.
</action>