8 min read

We will start by briefly looking at each of the logging frameworks mentioned above, and will then go into how the server logs events and errors and where it logs them to. After examining them, we will look into the different ways in which we can configure application logging.

  • Apache log4j: Log4j is an open source logging framework that is developed by the Apache Software Foundation. It provides a set of loggers, appenders, and layouts, to control which messages should be logged at runtime, where they should be logged to, and in what format they should be logged. The loggers are organized in a tree hierarchy, starting with the root logger at the top of the hierarchy. All loggers except the root logger are named entities and can be retrieved by their names. The root logger can be accessed by using the Logger.getRootLogger() API, while all other loggers can be accessed by using the Logger.getLogger() API. The names of the loggers follow the rule that the name of the parent logger followed by a ‘.’ is a prefix to the child logger’s name. For example, if com.logger.test is the name of a logger, then its direct ancestor is com.logger, and the prior ancestor is com.

    Each of the loggers may be assigned levels. The set of possible levels in an ascending order are—TRACE, DEBUG, INFO, WARN, ERROR, and FATAL. If a logger is not assigned a level, then it inherits its level from its closest ancestor. A log statement makes a logging request to the log4j subsystem. This request is enabled only if its logging level is higher than or equal to its logger’s level. If it is lower than the log, then the message is not output through the configured appenders.

    Log4j allows logs to be output to multiple destinations. This is done via different appenders. Currently there are appenders for the console, files, GUI components, JMS destinations, NT, and Unix system event loggers and remote sockets. Log4j is one of the most widely-used logging frameworks for Java applications, especially ones running on application servers. It also provides more features than the other logging framework that we are about to see, that is, the Java Logging API.

  • Java Logging API: The Java Logging API, also called JUL, from the java.util.logging package name of the framework, is another logging framework that is distributed with J2SE from version 1.4 onwards. It also provides a hierarchy of loggers such as log4j, and the inheritance of properties by child loggers from parents just like log4j. It provides handlers for handling output, and formatters for configuring the way that the output is displayed. It provides a subset of the functionality that log4j provides, but the advantage is that it is bundled with the JRE, and so does not require the application to include third-party JARS as log4j does.
  • SLF4J: The Simple Logging Facade for Java or SLF4J is an abstraction or facade over various logging systems. It allows a developer to plug in the desired logging framework at deployment time. It also supports the bridging of legacy API calls through the slf4j API, and to the underlying logging implementation. Versions of Apache Geronimo prior to 2.0 used Apache Commons logging as the facade or wrapper. However, commons logging uses runtime binding and a dynamic discovery mechanism, which came to be the source of quite a few bugs. Hence, Apache Geronimo migrated to slf4j, which allows the developer to plug in the logging framework during deployment, thereby eliminating the need for runtime binding.

Configuring Apache Geronimo logging

Apache Geronimo uses slf4j and log4j for logging. The log4j configuration files can be found in the /var/log directory. There are three configuration files that you will find in this directory, namely:

  • client-log4j.properties
  • deployer-log4j.properties
  • server-log4j.properties

Just as they are named, these files configure log4j logging for the client container (Java EE application client), deployer system, and the server.

You will also find the corresponding log files—client.log, deployer.log, and server.log. The properties files, listed above, contain the configuration of the various appenders, loggers, and layouts for the server, deployer, and client. As mentioned above, log4j provides a hierarchy of loggers with a granularity ranging from the entire server to each class on the server. Let us examine one of the configuration files: the server-log4j.properties file:

  • This file starts with the line log4j.rootLogger=INFO, CONSOLE, FILE. This means that the log4j root logger has a level of INFO and writes log statements to two appenders, namely, the CONSOLE appender and the FILE appender. These are the appenders that write to the console and to files respectively. The console appender and file appenders are configured to write to System.out and to /var/log/geronimo.log.
  • Below this section, there is a finer-grained configuration of loggers at class or package levels. For example, log4j.logger.openjpa.Enhance=TRACE.
  • It configures the logger for the class log4j.logger.openjpa.Enhance to the TRACE level. Note that all of the classes that do not have a log level defined will take on the log level of their parents. This applies recursively until we reach the root logger and inherit its log level (INFO in this case).

Configuring application logging

We will be illustrating how applications can log messages in Geronimo by using two logging frameworks, namely, log4j and JUL. We will also illustrate how you can use the slf4j wrapper to log messages with the above two underlying implementations. We will be using a sample application, namely, the HelloWorld web application to illustrate this.

Using log4j

We can use log4j for logging the application log to either a separate logfile or to the geronimo.log file. We will also illustrate how the logs can be written to a separate file in the /var/log directory, by using a GBean.

Logging to the geronimo.log file and the command console

Logging to the geronimo.log file and the command console is the simplest way to do application logging in Geronimo. For enabling this in your application, you only need to add logging statements to your application code. The HelloWorld sample application has a servlet called HelloWorldServlet, which has the following statements for enabling logging. The servlet is shown below.

package com.packtpub.hello;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.log4j.Logger;
public class HelloWorldServlet extends HttpServlet
{
Logger logger = Logger.getLogger(HelloWorldServlet.class.getName());
protected void service(HttpServletRequest req, HttpServletResponse
res)
throws ServletException, IOException {
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.print("");
logger.info("Printing out ");
out.print("Hello World Application");
logger.info("Printing out Hello World Application<br>title>");<br> out.print("");
logger.info("Printing out ");
out.print("Hello World
");
logger.info("Printing out Hello World
");
out.print("");
logger.info("Printing out ");
out.print("");
logger.info("Printing out ");
logger.warn("Sample Warning message");
logger.error("Sample error message");
}
}

Deploy the sample HelloWorld-1.0.war file, and then access http://localhost:8080/HelloWorld/. This servlet will log the following messages in the command console, as shown in the image below:

Apache Geronimo 2.1: Quick Reference

The geronimo.log file will have the following entries:

2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out 

2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out
Hello World Application

2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out

2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out Hello World



2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out

2009-02-02 20:01:38,906 INFO [HelloWorldServlet] Printing out

2009-02-02 20:01:38,906 WARN [HelloWorldServlet] Sample Warning message

2009-02-02 20:01:38,906 ERROR [HelloWorldServlet] Sample error message

Notice that only the messages with a logging level of greater than or equal to WARN are being logged to the command console, while all the INFO, ERROR, and WARN messages are logged to the geronimo.log file. This is because in server-log4j.properties the CONSOLE appender’s threshold is set to the value of the system property, org.apache.geronimo.log.ConsoleLogLevel, as shown below:

log4j.appender.CONSOLE.Threshold=${org.apache.geronimo.log.
ConsoleLogLevel}

The value of this property is, by default, WARN. All of the INFO messages are logged to the logfile because the FILE appender has a lower threshold, of TRACE, as shown below:

log4j.appender.FILE.Threshold=TRACE

Using this method, you can log messages of different severity to the console and logfile to which the server messages are logged. This is done for operator convenience, that is, only high severity log messages, such as warnings and errors, are logged to the console, and they need the operator’s attention. The other messages are logged only to a file.


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here