0
votes

I am running a Java EE project on Wildfly 10.1 Final.

I want to make a custom Log4j appender that logs to a JMS queue. I already made a Message Driven Bean in my Java EE app that receives the log messages from the queue.

I created my MDB by adding this annotation:

@MessageDriven(activationConfig = {
         @ActivationConfigProperty(propertyName = "destinationType", 
         propertyValue = "javax.jms.Queue"),
         @ActivationConfigProperty(propertyName = "destination", 
         propertyValue = "queue/MyQueue")
        })

This bean also implements MessageListener interface, and overrides it's onMessage() method where I defined the desired behaviour when the log message arrives. It looks something like this:

public class myBean implements MessageListener {

    @Override
    public void onMessage(Message msg) {

                        if(msg instanceof TextMessage){

                            TextMessage txtMess = (TextMessage)msg;
                            String context = (String)txtMess.getText();
                            processLogData(context);
    }
}

I also needed to add JMS to Wildfly's standalone.xml, by copying all the JMS related lines from standalone-full.xml. I also needed to add my queue to standalone.xml, by adding this line to :

<jms-queue name="SequenceQueue" entries="java:/jms/queue/MyQueue"/>

Now, I want to use the JMSQueueAppender class provided by apache, to send the log messages to MyQueue.

I am not sure, how should I do that. Where should I put the JMSQueueApender class? What values should I provide for queueConnectionFactoryBindingName and queueBindingName, and also for initialContextFactory and providerURL?

I read int this SO thread that I should put log4j.properties file in my EAR/META-INF. I also read in this SO thread how the log4j.properties should look like.

Still, I am not sure which values I need to provide to the JMSQueueApender class, and where should I put it (how will it be initialized).

Since my project is running inside the Application Server (Java EE enviroment), and my queue is a part of that container, can I write a more simple JMSQueuApender class. Something like this:

@Singleton
@Startup
public class JMSQueueAppender extends AppenderSkeleton {

    private Logger log = LoggerFactory.getLogger(LogSomethingBean.class);

    @Inject
    private JMSContext context;

    @Resource(mappedName = "java:/jms/queue/MyQueue")
    private Queue queue;

    public void append(LoggingEvent event) {
        try {
            TextMessage msg = queueSession.createTextMessage();

            String str = (String)event.getMessage();
            msg.setText(str);
            context.createProducer().send(queue, msg);
        } catch (JMSException e) {
            log.error("An error has occured while trying to send a msg to queue", e);
        }
    }

}

EDIT: would it be somehow possible to define one log4j.properties file for the whole Wildfly instance, so that every project that is running on it reads that configuration?

1

1 Answers

0
votes

I found out a way to use this appender on Wildfly 10.1 Final.

I used the JMSQueueApender class as is.

I added the log4j.properties file to the ear/application/META-INF (I am using Maven).

My log4j.properties looks like this:

log4j.rootLogger=INFO, stdout, jms

## 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=%d %-5p %c - %m%n

## Configure 'jms' appender
log4j.appender.jms=rs.netset.authority.log4j.JMSQueueAppender
log4j.appender.jms.initialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory
log4j.appender.jms.providerUrl=tcp://localhost:61616
log4j.appender.jms.queueBindingName=java:/jms/queue/MyQueue
log4j.appender.jms.queueConnectionFactoryBindingName=ConnectionFactory

And, everything works