Showing posts with label ActiveMQ. Show all posts
Showing posts with label ActiveMQ. Show all posts

Wednesday, August 12, 2015

Publishing WSO2 product logs to a Topic in Apache ActiveMQ.

Hi All,

This post will describe how the logs of a WSO2 product can be published to a topic in Apache ActiveMQ. WSO2 products use apache's log4j module for logging purposes. We will be using the "org.apache.log4j.net.JMSAppender" class to publish logs to a topic. ActiveMQ already has a guide on how this can be done [1].

log4j.properties

Add the following configuration to <WSO2_PRODUCT>/repository/conf/log4j.properties file.

log4j.appender.JMS_APPENDER=org.apache.log4j.net.JMSAppender
log4j.appender.JMS_APPENDER.InitialContextFactoryName=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.JMS_APPENDER.Append=true
log4j.appender.JMS_APPENDER.ProviderURL=tcp://127.0.0.1:61616
log4j.appender.JMS_APPENDER.TopicBindingName=dynamicTopics/logTopic
log4j.appender.JMS_APPENDER.TopicConnectionFactoryBindingName=ConnectionFactory

We also have to add the "JMS_APPENDER" logger to the root logger in log4j.properties file. Modify the following line...

log4j.rootLogger=ERROR, CARBON_CONSOLE, CARBON_LOGFILE, CARBON_MEMORY, CARBON_SYS_LOG, ERROR_LOGFILE

To the following...

log4j.rootLogger=ERROR, CARBON_CONSOLE, CARBON_LOGFILE, CARBON_MEMORY, CARBON_SYS_LOG, ERROR_LOGFILE, JMS_APPENDER

Dependency JAR files.

Add the following jar files from <ACTIVEMQ_HOME>/lib to <WSO2_PRODUCT>/repository/components/lib folder.

  • activemq-broker-5.*.jar
  • activemq-client-5.*.jar
  • geronimo-jms_1.1_spec-1.1.1.jar
  • geronimo-j2ee-management_1.1_spec-1.0.1.jar
  • hawtbuf-1.*.jar

Reading received log messages.

The logs are published as JMS ObjectMessages from the JMSAppender class. So therefore we wont be able to see the content of it directly. We would need to create a customer client by using the activemq dependency which can be downloaded or used as a pom dependency from here. The jar file is also available at the <ACTIVEMQ_HOME>/ folder. Using this dependency jar and the code below, we can extract the contents of the log messages.

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQObjectMessage;
import org.apache.log4j.spi.LoggingEvent;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;

public class Log4jJMSAppenderExample implements MessageListener {

    public Log4jJMSAppenderExample() throws Exception {
        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://127.0.0.1:61616");
        final Connection conn = factory.createConnection();
        final Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        conn.start();
        final MessageConsumer consumer = session.createConsumer(session.createTopic("logTopic"));
        consumer.setMessageListener(this);

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                try {
                    consumer.close();
                    session.close();
                    conn.close();
                } catch (JMSException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }

    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());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Notes

If there is a need to use the jndi.properties file, we will have to place it at the <WSO2_PRODUCT>/ folder instead of the <WSO2_PRODUCT>/repository/conf/. The jndi.properties file is not necessary as we have defined the topic in log4j.properties as "dynamicTopics/logTopic".

I have tested the above with WSO2 ESB 4.8.1 and Apache ActiveMQ 5.11.1.

References...

[1] - http://activemq.apache.org/how-do-i-use-log4j-jms-appender-with-activemq.html
[2] - https://docs.wso2.com/display/ESB481/Configure+with+ActiveMQ

Thursday, June 25, 2015

Configuring ActiveMQ to MySQL Database

Introduction...

Hi All,

By default, ActiveMQ broker uses KahaDB as the persistence message store. In the following post we will be configuring ActiveMQ to use a MySQL database.

Steps 1

Modify the "activemq.xml" file which is located at "<ACTIVEMQ_HOME>/conf/" folder. Here we have to add a bean which contains the connection details for the MySQL database and also have to indicate that we are gonna use MySQL as the message store.

Add the MySQL database connection information as below.

<beans .....>
    ......
    <bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/activemq"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="poolPreparedStatements" value="true"/>
    </bean>
    ......
</beans>

Remove the KahaDB message store and add the MySQL message store.

<beans .....>
    <broker .....>
        ......
        <persistenceAdapter>
            <jdbcPersistenceAdapter dataSource="#mysql-ds"/>
            <!-- <kahaDB directory="${activemq.data}/kahadb"/> -->
        </persistenceAdapter>
        ......
    </broker>
</beans>

Steps 2

Add the MySQL driver to "<ACTIVEMQ_HOME>/lib/optional/" folder

And thats all folks.

References...

[1] - http://activemq.apache.org/how-to-configure-a-new-database.html
[2] - http://activemq.2283324.n4.nabble.com/ActiveMQ-4-0-won-t-start-td2343357.html