Nowadays I am searching how to arrange applications’ log which is written on append mode. The logs are not readable and are not convenient for management. Therefore JMS queue or topic(this selection depends on your needs) was seen the best solution in order to achieve my goal. In that case, Apache Active MQ might be a considerable option and in this entry I explain the integration step by step.
In order to active the ActiveMQ first you need to deploy activemq-web-console-5.5.1.war (version changes)(http://activemq.apache.org/web-console.html). Make sure that the web application is up .Replace localhost to 0.0.0.0 in the activemq.xml file for remote calling.
I edit log4.properties file the way stated as below to send log4j messages to my topic.
log4j.rootLogger=INFO, stdout,jms2
## Be sure that ActiveMQ messages are not logged to ‘jms’ appender
log4j.logger.org.apache.activemq=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[Console Adapter]%d %-5p %c – %m%n
## Configure ‘jms’ appender. You’ll also need jndi.properties file in order to make it work
log4j.appender.jms2=org.apache.log4j.net.JMSAppender
log4j.appender.jms2.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.jms2.ProviderURL=tcp://ip:61616
log4j.appender.jms2.TopicBindingName=dynamicTopics/logTopic
log4j.appender.jms2.TopicConnectionFactoryBindingName=ConnectionFactory
Log4jJMSAppenderExample class demonstrates the general usage of ActiveMq.Client sends log4j messages to the topic and topic prints the received message.
import java.net.URL;
import java.util.Properties;
import javax.jms.Connection;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.activemq.command.ActiveMQTopic;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.spi.LoggingEvent;
public class Log4jJMSAppenderExample implements MessageListener {
public Log4jJMSAppenderExample() throws Exception {
PropertyConfigurator.configure(load("jndi.properties"));
Properties ppt2 = new Properties();
ppt2.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.activemq.jndi.ActiveMQInitialContextFactory");
ppt2.put(Context.PROVIDER_URL, "tcp://127.0.0.1:61616");
ppt2.put("topic.logTopic", "logTopic");
Context ctx2 = new InitialContext(ppt2);
PropertyConfigurator.configure(load("log4j.properties"));
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("failover://(tcp://ip:61616,tcp://ip:61616)?initialReconnectDelay=100&randomize=false");
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://ip:61616");
Connection conn = factory.createConnection();
Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn.start();
MessageConsumer consumer = sess.createConsumer(sess.createTopic("logTopic"));
MessageConsumer consumer = sess.createConsumer(new ActiveMQTopic("logTopic"));
consumer.setMessageListener(this);
// log a message
Logger log = Logger.getLogger(Log4jJMSAppenderExample.class);
for (int i = 0; i < 10; i++) {
log.error("Error log message:");
}
Thread.sleep(1000);
consumer.close();
sess.close();
conn.close();
System.exit(1);
}
public Properties load(String propsName) throws Exception{
Properties props = new Properties();
URL url = getClass().getResource("./" + propsName);
props.load(url.openStream());
return props;
}
public static void main(String[] args) throws Exception{
new Log4jJMSAppenderExample();
}
public void onMessage(javax.jms.Message message){
try {
// receive log event in your consumer
LoggingEvent event = (LoggingEvent)((ActiveMQObjectMessage)message).getObject();
System.out.println("Received log [" + event.getLevel() + "]: " + event.getMessage() + " getFQNOfLoggerClass:" + event.getFQNOfLoggerClass() + " getLoggerName"
+ event.getLoggerName() + " getNDC:" + event.getNDC() + " getRenderedMessage:" + event.getRenderedMessage() + " getThreadName :" + event.getThreadName() + "\n"
+ " getClassName:" + event.getLocationInformation().getClassName() + " getMetodName:" + event.getLocationInformation().getMethodName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
Beside this class the proper implementation is implementing a MDB application on the server side in order to listen JMS messages. Spring provides easier configuration in case of comparison with the EJB. ApplicationContext.xml is shown below. It provides a listener for a specific queue.