Volume 6, Issue 5
Distributed Logging Using The Java Messsage Service, by David Chappell and Greg Pavlik

Listing 1: Interface for the logging client to send messages to a log service
 

package util.log;
/**
 * Title: ClientLog
 * Description: Interface defining the logging API used by
   logging clients.
 * @author Greg Pavlik
 * @author David Chappell
 */
public interface ClientLog
{
  public void logMessage(String message) throws LogException;
}
 
 

Listing 2: The JMS-based implementation of the ClientLog interface
package util.log;
import javax.jms.*;
 

/**
 * Title: JMSClientLogImpl
 * Description: Implementation of logging service logging
   client API; uses JMS
 * to send the application log.
 * @author Greg Pavlik
 * @author David Chappell
 */
 

public class JMSClientLogImpl implements ClientLog
{
  /** queue sender for connection */
  private QueueSender m_sender = null;
  /** queue session for connection */
  private QueueSession m_session = null;
 

  /**
   * No arg constructor for log service implementation.
   * Acquire a reference to administered queue via standard
   * JNDI lookups.
   * @param initialContextFactory initial context factory
   * @exception thrown if constructor cannot initialize queue
      sender
   */
  public JMSClientLogImpl(String initialContextFactory) throws LogException
  {
      try
      {
        //acquire JMS queue reference via JNDI
        java.util.Hashtable env = new java.util.Hashtable();
        env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
        initialContextFactory);
        javax.naming.InitialContext context = new
        javax.naming.InitialContext(env);
        QueueConnectionFactory qcf = (QueueConnectionFactory)
        context.lookup("QueueConnectionFactory");
        QueueConnection connection = qcf.createQueueConnection();
        QueueSession session = connection.createQueueSession
        (false, QueueSession.AUTO_ACKNOWLEDGE);
        Queue queue = (Queue)context.lookup("LogQueue");
        m_sender = session.createSender(queue);
      }
      catch (Exception e)
      {
        throw new LogException(e.getMessage());
      }
  }
 

  /**
   * Takes an input string and pushes message on to log queue
   * @param logEntry the input String
   */
  public void logMessage(String logEntry) throws LogException
  {
      try
      {
        TextMessage message = m_session.createTextMessage();
        message.setText(logEntry);
        m_sender.send(message);
      }
      catch (Exception e)
      {
        throw new LogException(e.getMessage());
      }
  }
}
 
 

Listing 3: A factory class for the implementation of the ClientLog interface
package util.log;
/**
 * Title: ClientLogFactory
 * Description: Acts as a factory maintaining implementation
   of ClientLog as a singleton instance.
 * @author Greg Pavlik
 * @author David Chappell
 */
 

public class ClientLogFactory
{
  /** client log implementation returned by factory */
  static private ClientLog m_logImpl = null;
 

  static
  {
     //hard code for example
     m_logImpl = new JMSClientLogImpl("JMS Initial Context Factory");
  }
 

  /**
   * provides access to singleton instance
   * @return implementation of ClientLog interface
   */
  static public ClientLog instance() throws LogException
  {
      return m_logImpl;
  }
}
 
 

Listing 4: A message listener that sends text to standard error on monitoring console
package util.log;
/**
 * Title: LogServiceMessageListener
 * Description: Message Listener for distributed log example.
   This example extracts the message text from the message
   and writes it to standard err.
 * @author Greg Pavlik
 * @author David Chappell
 */
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.TextMessage;
 

public class LogServiceMessageListener implements MessageListener
{
  /**
   * Send message contents to standard error
   * @param message the text message sent from
   */
  public void onMessage(Message message)
  {
      try
      {
        String text = ((TextMessage)message).getText();
        System.err.println(text);
      }
      catch(Exception e)
      {
        System.err.println("SYSTEM ERROR: could not process
        message: " + message);
      }
  }
}
 
 

Listing 5: A tag extension for JSPs
package util.log;
/**
 * Title: LogClientTag
 * Description: A tag extension for JSPs that uses the
   ClientLog implementation.
 * This can be used to send log messages to the JMS queue without
 * writing any Java code.
 * @author Greg Pavlik
 * @author David Chappell
 */
 

import javax.servlet.jsp.tagext.TagSupport;
 

public class LogClientTag extends TagSupport
{
 

  /** Client log message set by JSP engine during tag processing*/
  private String m_message = null;
 

  /** no arg constructor */
  public LogClientTag()
  {
    ;
  }
 

  /**
   * After tag has been encountered, simply send text to ClientLog
   */
  public int doEndTag() throws javax.servlet.jsp.JspException
  {
        try
        {
            ClientLogFactory.instance().logMessage(m_message);
            return javax.servlet.jsp.tagext.Tag.SKIP_BODY;
        }
        catch (LogException e)
        {
            throw new javax.servlet.jsp.JspException(e.getMessage());
        }
    }
 

    //ATTRIBUTE ACCESSOR/MUTATORS
    public void setMessage(String value)
    {
        m_message = value;
    }
 

    public String getMessage()
    {
        return m_message;
    }
}