ULC Log4J Integration

Purpose

Every serious application needs logging. During development it helps to debug an application and in production logging is an indispensable means to reconstruct application misbehavior. In addition, some applications need to trace all activities for legal reasons.

This contribution demonstrates how to integrate the popular open-source Log4J logging framework into ULC.

By replacing the standard ULC logging manager, all ULC framework logs will be delegated to the Log4J framework. The application code can call the Log4J framework directly. It is achieved that all logging messages from the ULC framework and from the application are gathered and processed by the Log4J framework.

Related To

How to use

After starting our application on the server-side, we set the Log4jLogManager at the earliest moment possible. In the development environment, this will be before starting the TemplateDevelopmentRunner. In the servlet environment, this will be in the init method of a custom ServletContainerAdapter. In the EJB environment, this will be in the ejbCreate method of a custom EjbContainerAdapterBean. A sample servlet container integration is shown below.

public class Log4jExampleServletContainerAdapter extends ServletContainerAdapter
{
  public void init() throws ServletException
  {
    Log4jLogManager log4jLogManager = new Log4jLogManager();
    LogManager.setLogManager(log4jLogManager);
    super.init();
  }
}


Configuration of the logging output is done in Log4J's common way. Usually, this means configuring a file called log4j.properties and putting it on the classpath. A sample configuration file is shown below.
log4j.rootLogger=OFF,ConsoleAppender
log4j.logger.com.ulcjava=WARN log4j.logger.com.canoo.template=INFO

log4j.appender.ConsoleAppender=org.apache.log4j.ConsoleAppender log4j.appender.ConsoleAppender.layout=org.apache.log4j.PatternLayout log4j.appender.ConsoleAppender.layout.conversionPattern=%-6r %-6p %d{DATE} [%-35t] %50c - %m%n


We can now add logging statements to our application code in the well-known Log4J fashion.

How it is implemented

The Log4J integration is achieved by setting a custom log manager which is derived from ULC's LogManager class.
LogManager logManager = new Log4jLogManager();
LogManager.setLogManager(logManager);

This Log4JLogManager provides Log4jLogger instances. A Log4jLogger serves as a delegate to Log4J's loggers. It converts the ULC logging levels to the Log4J logging levels and then calls the appropriate logging method on the Log4J framework.
public class Log4jLogger extends Logger
{
  ...


public void info(String msg) { org.apache.log4j.Level log4jLogLevel = getMapping(Level.INFO); fLog4jLogger.log(log4jLogLevel, msg); }
...
}

Resources