You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2017/06/01 03:04:51 UTC
logging-log4j2 git commit: [LOG4J2-1294] The JMS Appender should use
a JMS MapMessage for a Log4j MapMessage.
Repository: logging-log4j2
Updated Branches:
refs/heads/master dc26e2387 -> e89ac6e5b
[LOG4J2-1294] The JMS Appender should use a JMS MapMessage for a Log4j
MapMessage.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/e89ac6e5
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/e89ac6e5
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/e89ac6e5
Branch: refs/heads/master
Commit: e89ac6e5b16d15497c12758665dbbfb1534eb13d
Parents: dc26e23
Author: Gary Gregory <gg...@apache.org>
Authored: Wed May 31 20:04:48 2017 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Wed May 31 20:04:48 2017 -0700
----------------------------------------------------------------------
.../appender/mom/activemq/JmsAppenderIT.java | 222 +++++++++++--------
.../log4j/core/appender/mom/JmsManager.java | 37 +++-
.../log4j/core/layout/MessageLayout.java | 66 ++++++
src/changes/changes.xml | 3 +
4 files changed, 229 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e89ac6e5/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/mom/activemq/JmsAppenderIT.java
----------------------------------------------------------------------
diff --git a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/mom/activemq/JmsAppenderIT.java b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/mom/activemq/JmsAppenderIT.java
index 4e03e46..b0bf594 100644
--- a/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/mom/activemq/JmsAppenderIT.java
+++ b/log4j-core-its/src/test/java/org/apache/logging/log4j/core/appender/mom/activemq/JmsAppenderIT.java
@@ -17,11 +17,16 @@
package org.apache.logging.log4j.core.appender.mom.activemq;
+import static org.junit.Assert.assertEquals;
+
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -31,114 +36,145 @@ import javax.jms.ObjectMessage;
import org.apache.activemq.jndi.ActiveMQInitialContextFactory;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.categories.Appenders;
+import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.mom.JmsAppender;
import org.apache.logging.log4j.core.appender.mom.JmsManager;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
+import org.apache.logging.log4j.core.layout.MessageLayout;
import org.apache.logging.log4j.core.layout.SerializedLayout;
import org.apache.logging.log4j.core.net.JndiManager;
+import org.apache.logging.log4j.message.MapMessage;
import org.apache.logging.log4j.message.SimpleMessage;
-import org.junit.AfterClass;
+import org.junit.After;
+import org.junit.Assert;
import org.junit.Before;
-import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-import static org.junit.Assert.*;
-
/**
* Integration test for JmsAppender using an embedded ActiveMQ broker.
*/
@Category(Appenders.Jms.class)
public class JmsAppenderIT {
- private static final String KEY_SERIALIZABLE_PACKAGES = "org.apache.activemq.SERIALIZABLE_PACKAGES";
-
- private static JmsManager jmsManager;
-
- private JmsAppender appender;
-
- @BeforeClass
- public static void setUpClass() {
- System.setProperty(KEY_SERIALIZABLE_PACKAGES,
- "org.apache.logging.log4j.core.impl,org.apache.logging.log4j.util,org.apache.logging.log4j,java.rmi");
- final Properties additional = new Properties();
- additional.setProperty("queue.TestQueue", "TestQueue");
- final JndiManager jndiManager = JndiManager.getJndiManager(ActiveMQInitialContextFactory.class.getName(),
- "vm://localhost?broker.persistent=false", null, null, null, additional);
- jmsManager = JmsManager.getJmsManager("JmsManager", jndiManager, "ConnectionFactory", "TestQueue", null, null);
- }
-
- @AfterClass
- public static void tearDownClass() {
- jmsManager.close();
- System.getProperties().remove(KEY_SERIALIZABLE_PACKAGES);
- }
-
- @Before
- public void setUp() throws Exception {
- // @formatter:off
- appender = JmsAppender.newBuilder().
- setName("JmsAppender").
- setLayout(SerializedLayout.createLayout()).
- setIgnoreExceptions(true).
- setJmsManager(jmsManager).
- build();
- // @formatter:off
- appender.start();
- }
-
- @Test
- public void testLogToQueue() throws Exception {
- final int messageCount = 100;
- final MessageConsumer messageConsumer = jmsManager.createMessageConsumer();
- final JmsQueueConsumer consumer = new JmsQueueConsumer(messageCount);
- messageConsumer.setMessageListener(consumer);
- final String messageText = "Hello, World!";
- final String loggerName = this.getClass().getName();
- for (int i = 0; i < messageCount; i++) {
- final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName(loggerName) //
- .setLoggerFqcn(loggerName).setLevel(Level.INFO) //
- .setMessage(new SimpleMessage(messageText)).setThreadName(Thread.currentThread().getName()) //
- .setTimeMillis(System.currentTimeMillis()).build();
- appender.append(event);
- }
- consumer.awaitAndAssertAllMessagesConsumed();
- }
-
- private static class JmsQueueConsumer implements MessageListener {
-
- private final int messageCount;
- private final CountDownLatch countDownLatch;
- private final Collection<LogEvent> events;
-
- private JmsQueueConsumer(final int messageCount) {
- this.messageCount = messageCount;
- this.countDownLatch = new CountDownLatch(messageCount);
- this.events = new ArrayList<>(messageCount);
- }
-
- @Override
- public void onMessage(final Message message) {
- try {
- consume((ObjectMessage) message);
- } catch (final JMSException e) {
- e.printStackTrace();
- }
- }
-
- private void consume(final ObjectMessage message) throws JMSException {
- try {
- final LogEvent event = (LogEvent) message.getObject();
- events.add(event);
- } finally {
- countDownLatch.countDown();
- }
- }
-
- public void awaitAndAssertAllMessagesConsumed() throws InterruptedException {
- countDownLatch.await(5, TimeUnit.SECONDS);
- assertEquals(messageCount, events.size());
- }
- }
+ private static final String KEY_SERIALIZABLE_PACKAGES = "org.apache.activemq.SERIALIZABLE_PACKAGES";
+
+ private JmsManager jmsManager;
+
+ private JmsAppender appender;
+
+ @Before
+ public void setUpClass() {
+ System.setProperty(KEY_SERIALIZABLE_PACKAGES,
+ "org.apache.logging.log4j.core.impl,org.apache.logging.log4j.util,org.apache.logging.log4j,java.rmi");
+ final Properties additional = new Properties();
+ additional.setProperty("queue.TestQueue", "TestQueue");
+ final JndiManager jndiManager = JndiManager.getJndiManager(ActiveMQInitialContextFactory.class.getName(),
+ "vm://localhost?broker.persistent=false", null, null, null, additional);
+ jmsManager = JmsManager.getJmsManager("JmsManager", jndiManager, "ConnectionFactory", "TestQueue", null, null);
+ }
+
+ @After
+ public void tearDownClass() {
+ jmsManager.close();
+ System.getProperties().remove(KEY_SERIALIZABLE_PACKAGES);
+ }
+
+ private void setUp(Layout<?> layout) throws Exception {
+ // @formatter:off
+ appender = JmsAppender.newBuilder()
+ .setName("JmsAppender")
+ .setLayout(layout)
+ .setIgnoreExceptions(true)
+ .setJmsManager(jmsManager)
+ .build();
+ // @formatter:off
+ appender.start();
+ }
+
+ @Test
+ public void testLogMapMessageToQueue() throws Exception {
+ setUp(MessageLayout.createLayout());
+ final int messageCount = 100;
+ final MessageConsumer messageConsumer = jmsManager.createMessageConsumer();
+ final JmsQueueConsumer consumer = new JmsQueueConsumer(messageCount, javax.jms.MapMessage.class);
+ messageConsumer.setMessageListener(consumer);
+ final String messageText = "Hello, World!";
+ final String loggerName = this.getClass().getName();
+ for (int i = 0; i < messageCount; i++) {
+ Map<String, String> map = new HashMap<>();
+ map.put("messageText", messageText);
+ map.put("threadName", Thread.currentThread().getName());
+ final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName(loggerName) //
+ .setLoggerFqcn(loggerName).setLevel(Level.INFO) //
+ .setMessage(new MapMessage(map)) //
+ .setTimeMillis(System.currentTimeMillis()).build();
+ appender.append(event);
+ }
+ consumer.awaitAndAssertAllMessagesConsumed();
+ }
+
+ @Test
+ public void testLogObjectMessageToQueue() throws Exception {
+ setUp(SerializedLayout.createLayout());
+ final int messageCount = 100;
+ final MessageConsumer messageConsumer = jmsManager.createMessageConsumer();
+ final JmsQueueConsumer consumer = new JmsQueueConsumer(messageCount, ObjectMessage.class);
+ messageConsumer.setMessageListener(consumer);
+ final String messageText = "Hello, World!";
+ final String loggerName = this.getClass().getName();
+ for (int i = 0; i < messageCount; i++) {
+ final LogEvent event = Log4jLogEvent.newBuilder().setLoggerName(loggerName) //
+ .setLoggerFqcn(loggerName).setLevel(Level.INFO) //
+ .setMessage(new SimpleMessage(messageText)).setThreadName(Thread.currentThread().getName()) //
+ .setTimeMillis(System.currentTimeMillis()).build();
+ appender.append(event);
+ }
+ consumer.awaitAndAssertAllMessagesConsumed();
+ }
+
+ private static class JmsQueueConsumer implements MessageListener {
+
+ private final int messageCount;
+ private final Class<? extends Message> messageClass;
+ private final CountDownLatch countDownLatch;
+ private final Collection<Object> events;
+
+ private JmsQueueConsumer(final int messageCount, Class<? extends Message> messageClass) {
+ this.messageCount = messageCount;
+ this.messageClass = messageClass;
+ this.countDownLatch = new CountDownLatch(messageCount);
+ this.events = new ArrayList<>(messageCount);
+ }
+
+ @Override
+ public void onMessage(final Message message) {
+ try {
+ try {
+ final Object event;
+ Assert.assertTrue(String.format("Expected type '%s' to be an instance of %s", message.getClass(), messageClass),
+ messageClass.isAssignableFrom(message.getClass()));
+ if (message instanceof ObjectMessage) {
+ event = ((ObjectMessage) message).getObject();
+ } else if (message instanceof javax.jms.MapMessage) {
+ event = message;
+ } else {
+ Assert.fail("Unexpected Message type: " + message);
+ event = null;
+ }
+ events.add(event);
+ } finally {
+ countDownLatch.countDown();
+ }
+ } catch (final JMSException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void awaitAndAssertAllMessagesConsumed() throws InterruptedException {
+ countDownLatch.await(5, TimeUnit.SECONDS);
+ assertEquals(messageCount, events.size());
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e89ac6e5/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
index 4ff0f05..db47743 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/mom/JmsManager.java
@@ -18,12 +18,14 @@
package org.apache.logging.log4j.core.appender.mom;
import java.io.Serializable;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
+import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
@@ -107,13 +109,23 @@ public class JmsManager extends AbstractManager {
}
/**
- * Creates a TextMessage or ObjectMessage from a Serializable object. For instance, when using a text-based
- * {@link org.apache.logging.log4j.core.Layout} such as {@link org.apache.logging.log4j.core.layout.PatternLayout},
- * the {@link org.apache.logging.log4j.core.LogEvent} message will be serialized to a String. When using a
- * layout such as {@link org.apache.logging.log4j.core.layout.SerializedLayout}, the LogEvent message will be
- * serialized as a Java object.
+ * Creates a TextMessage, MapMessage, or ObjectMessage from a Serializable object.
+ * <p>
+ * For instance, when using a text-based {@link org.apache.logging.log4j.core.Layout} such as
+ * {@link org.apache.logging.log4j.core.layout.PatternLayout}, the {@link org.apache.logging.log4j.core.LogEvent}
+ * message will be serialized to a String.
+ * </p>
+ * <p>
+ * When using a layout such as {@link org.apache.logging.log4j.core.layout.SerializedLayout}, the LogEvent message
+ * will be serialized as a Java object.
+ * </p>
+ * <p>
+ * When using a layout such as {@link org.apache.logging.log4j.core.layout.MessageLayout} and the LogEvent message
+ * is a Log4j MapMessage, the message will be serialized as a JMS MapMessage.
+ * </p>
*
- * @param object The LogEvent or String message to wrap.
+ * @param object
+ * The LogEvent or String message to wrap.
* @return A new JMS message containing the provided object.
* @throws JMSException
*/
@@ -121,9 +133,22 @@ public class JmsManager extends AbstractManager {
if (object instanceof String) {
return this.session.createTextMessage((String) object);
}
+ else if (object instanceof org.apache.logging.log4j.message.MapMessage) {
+ return map((org.apache.logging.log4j.message.MapMessage) object, this.session.createMapMessage());
+ }
return this.session.createObjectMessage(object);
}
+ private MapMessage map(org.apache.logging.log4j.message.MapMessage log4jMapMessage, MapMessage jmsMapMessage)
+ throws JMSException {
+ // Call getData() only once.
+ final Map<String, String> data = log4jMapMessage.getData();
+ for (Map.Entry<String, String> entry : data.entrySet()) {
+ jmsMapMessage.setString(entry.getKey(), entry.getValue());
+ }
+ return jmsMapMessage;
+ }
+
@Override
protected boolean releaseSub(final long timeout, final TimeUnit timeUnit) {
boolean closed = true;
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e89ac6e5/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MessageLayout.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MessageLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MessageLayout.java
new file mode 100644
index 0000000..9adb8ee
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/MessageLayout.java
@@ -0,0 +1,66 @@
+/*
+ * 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.layout;
+
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Node;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.message.Message;
+
+/**
+ * Formats a {@link LogEvent} in its {@link Message} form.
+ * <p>
+ * Useful in combination with a JMS Appender to map a Log4j {@link org.apache.logging.log4j.message.MapMessage} to a JMS
+ * {@link javax.jms.MapMessage}.
+ * </p>
+ */
+@Plugin(name = "MessageLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
+public class MessageLayout extends AbstractLayout<Message> {
+
+ public MessageLayout(Configuration configuration, byte[] header, byte[] footer) {
+ super(configuration, header, footer);
+ }
+
+ public MessageLayout() {
+ super(null, null, null);
+ }
+
+ @Override
+ public byte[] toByteArray(LogEvent event) {
+ return null;
+ }
+
+ @Override
+ public Message toSerializable(LogEvent event) {
+ return event.getMessage();
+ }
+
+ @Override
+ public String getContentType() {
+ return null;
+ }
+
+ @PluginFactory
+ public static Layout<?> createLayout() {
+ return new MessageLayout();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/e89ac6e5/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 3863f37..4936876 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -73,6 +73,9 @@
<action issue="LOG4J2-1860" dev="mikes" type="add">
Shortcut to add Property and KeyValuePair component in ConfigurationBuilder.
</action>
+ <action issue="LOG4J2-1294" dev="ggregory" type="add">
+ The JMS Appender should use a JMS MapMessage for a Log4j MapMessage.
+ </action>
<action issue="LOG4J2-1868" dev="ggregory" type="update">
Update ZeroMQ's JeroMQ from 0.3.6 to 0.4.0.
</action>