Один из способов подключения Log4j к J2EE приложению на cервере JBoss 4.2

Пример подключения сервиса Apache Log4j к J2EE приложению на cервере JBoss 4.2. Статья включает в себя фрагменты исходного кода. Тестовые примеры доступны для скачивания.

Сервер приложений JBoss в качестве системы логирования использует framework Apache Log4j. Основные настройки сервиса Log4j находятся в файле jboss\server\default\conf\jboss-service.xml в разделе Log4j Initialization.

Здесь можно задать несколько важных параметров, в том числе и ConfigurationUrl — местонахождение файла конфигурации сервиса Log4j. Сам файл конфигурации по умолчанию называется jboss-log4j.xml и находится в этой же папке.

Если у Вас есть полный доступ к управлению сервером, то самым простым способом подключить Log4j к приложению будет добавление конфигурации логов в этот файл. В случае отсутствия доступа к конфигурации сервера или если необходимо запускать несколько приложений на одном сервере или другой причине, создать собственный файл конфигурации и подгружать его при запуске приложения.

Один из возможных способов это сделать, показан ниже. На примере сервлета, класса и бина управляемого сообщениями:

Итак, сервер приложений JBoss4.2, Среда разработки Eclipse Средство автоматической сборки приложений Apache Ant.

Создадим в Eclipse новый java проект. Я назвал его JBoss_Log4j. Исходники будут в папке src скомпилированные файлы в папке bin.

Создадим папку lib, скопируем в нее несколько библиотек из сервера JBoss

  • jbossall-client.jar
  • jboss-ejb3x.jar
  • log4j.jar
  • servlet-api.jar

Приступим.
Начнем, пожалуй, с бина управляемого сообщениями — JBossLog4jTestMDB — так как он самый простой.

 package jboss_log4j.ejb;

 import javax.annotation.PostConstruct;
 import javax.annotation.PreDestroy;
 import javax.ejb.ActivationConfigProperty;
 import javax.ejb.MessageDriven;
 import javax.jms.Message;
 import jboss_log4j.common.Log4jServletInit;
 import org.jboss.logging.Logger;

 @MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination", propertyValue="queue/JBossLog4jTestMDBQueue")}) 
	public class JBossLog4jTestMDB  implements javax.jms.MessageListener{

		private static final long serialVersionUID = 1L;
		private static Logger logger=Log4jServletInit.getLogger(JBossLog4jTestMDB.class,"/META-INF/log4j.xml");
		// hash code of this object:
		private int hashCode;

		@PostConstruct
		public void ejbCreate() {
			hashCode = this.hashCode();
			logger.info("JBossLog4jTestMDB created: " + hashCode);
		}

		@PreDestroy
		public void ejbRemove() {
			logger.info("JBossLog4jTestMDB removed: " + hashCode);
		}	

		public void onMessage(Message message) {
			logger.debug("->Start, thread ID: " + Thread.currentThread().getId());
			logger.info("Message received: "+message);
		}
	}

Строчки, которые относятся к Log4j и непосредственно логированию, в этом и последующих примерах выделены зеленым цветом.

Теперь добавим следующий класс:

 package jboss_log4j;

 import java.util.Hashtable;
 import java.util.Map;
 import javax.jms.Connection;
 import javax.jms.ConnectionFactory;
 import javax.jms.JMSException;
 import javax.jms.Message;
 import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.QueueSession;
 import javax.jms.Session;
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import jboss_log4j.common.Log4jServletInit;
 import org.jboss.logging.Logger;

 public class JBossLog4jTest {

  private static Logger logger = Log4jServletInit.getLogger(JBossLog4jTest.class, "/META-INF/log4j.xml");

  public JBossLog4jTest() {
   super();
  }

  public void sendMessage(String traced_value) {
   logger.info("sendMessage start..");

   // send the message via controller queue
   logger.info("Traced Value :"+traced_value);
   Map messageParams = new Hashtable();
   messageParams.put("traced_value", traced_value);
   messageParams.put("my_message", "Hello from JBossLog4jTest");
   // create a connection to a controller queue 
   Connection connection = null;
   Session session = null;
   MessageProducer producer = null;
   Context ctx;
   ConnectionFactory connectionFactory;
   Queue controllerQueue;
   try {

    ctx = new InitialContext();
    connectionFactory = (ConnectionFactory)ctx.lookup("ConnectionFactory");
    logger.debug("ConnectionFactory ready.");
    controllerQueue	= (Queue)ctx.lookup("queue/JBossLog4jTestMDBQueue");
    logger.debug("Queue ready.");
    connection 	= connectionFactory.createConnection();
    session	= connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
    producer = session.createProducer(controllerQueue);	
    logger.debug("MessageProducer ready.");
    Message message	= session.createMessage();
    for (String key : messageParams.keySet()) {
     message.setStringProperty(key, messageParams.get(key));
    }
    // specify a message expiration
    int messageTTL		= 10*1000;	// 10 sec
    message.setJMSExpiration(messageTTL);

    // send a message
    producer.send(message);			
   } catch (NamingException e) {
    logger.error("NamingException: "+e.getMessage());
    e.printStackTrace();
   } catch (JMSException e) {
    logger.error("JMSException: "+e.getMessage());
    e.printStackTrace();
   }
   logger.info("Message successfully sent.");		
  }

 }

Как видим — из этого класса мы будем посылать сообщения ранее созданному бину управляемому сообщениями.

Ну и, наконец, напишем сервлет.

 package jboss_log4j;

 import java.util.Hashtable;
 import java.util.Map;
 import javax.jms.Connection;
 import javax.jms.ConnectionFactory;
 import javax.jms.JMSException;
 import javax.jms.Message;
 import javax.jms.MessageProducer;
 import javax.jms.Queue;
 import javax.jms.QueueSession;
 import javax.jms.Session;
 import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
 import jboss_log4j.common.Log4jServletInit;
 import org.jboss.logging.Logger;

 public class JBossLog4jTest {

  private static Logger logger = Log4jServletInit.getLogger(JBossLog4jTest.class, "/META-INF/log4j.xml");

  public JBossLog4jTest() {
   super();
  }

  public void sendMessage(String traced_value) {
   logger.info("sendMessage start..");

   // send the message via controller queue
   logger.info("Traced Value :"+traced_value);
   Map messageParams = new Hashtable();
   messageParams.put("traced_value", traced_value);
   messageParams.put("my_message", "Hello from JBossLog4jTest");
   // create a connection to a controller queue 
   Connection connection = null;
   Session session = null;
   MessageProducer producer = null;
   Context ctx;
   ConnectionFactory connectionFactory;
   Queue controllerQueue;
   try {

    ctx = new InitialContext();
    connectionFactory = (ConnectionFactory)ctx.lookup("ConnectionFactory");
    logger.debug("ConnectionFactory ready.");
    controllerQueue	= (Queue)ctx.lookup("queue/JBossLog4jTestMDBQueue");
    logger.debug("Queue ready.");
    connection 	= connectionFactory.createConnection();
    session	= connection.createSession(false, QueueSession.AUTO_ACKNOWLEDGE);
    producer = session.createProducer(controllerQueue);	
    logger.debug("MessageProducer ready.");
    Message message	= session.createMessage();
    for (String key : messageParams.keySet()) {
     message.setStringProperty(key, messageParams.get(key));
    }
    // specify a message expiration
    int messageTTL		= 10*1000;	// 10 sec
    message.setJMSExpiration(messageTTL);

    // send a message
    producer.send(message);			
   } catch (NamingException e) {
    logger.error("NamingException: "+e.getMessage());
    e.printStackTrace();
   } catch (JMSException e) {
    logger.error("JMSException: "+e.getMessage());
    e.printStackTrace();
   }
   logger.info("Message successfully sent.");		
  }

 }

Страница: