Using SLF4J in Community Edition
The Simple Logging Facade for Java (SLF4J) serves as a simple facade for various logging APIs, which lets you plug in the desired implementation at deployment time. SLF4j does not invent another logging framework, but lets application use a standard API and plug in the actual logging implementation at the deployment time.
SLF4j supports multiple logging systems, such as, NOP, Simple, Log4j version 1.2, java.util.logging, JCL and logback. The SLF4j distribution ships with several JAR files:
-
slf4j-nop.jar
-
slf4j-simple.jar
-
slf4j-log4j12.jar
-
slf4j-log4j13.jar
-
slf4j-jdk14.jar
-
slf4j-jcl.jar.
Each of these jar files is hardwired at compile-time to use just one implementation. All of the bindings shipped with SLF4j depend on slf4j-api.jar, which must be present on the class path for the binding to function properly. It also provides a migration path for applications using concrete logging implementations using bridge modules. Community Edition ships with these libraries that you can use in applications:
-
slf4j-api-1.4.3.jar
-
slf4j-log4j12-1.4.3.jar
-
jcl104-over-slf4j-1.4.3.jar
In this section, we show the use of SLF4j in the following ways.
-
Configure SLF4j to use the server Log4j configuration
-
Configure SLF4j using Log4j at the application level
Configure SLF4j to use the server Log4j configuration
In this section, we use the SLF4j API in the EMPDemo servlet instead of the Log4j API.
However, it uses Log4j implementation configured at the server level for concrete
implementation. Listing 15 shows the servlet code:
Listing 15. EMPDemo servlet using the SLF4j API
Logger logger = LoggerFactory.getLogger(EMPDemo.class.getName());
Connection con = null;
Statement stmt = null;
PrintWriter out = response.getWriter();
logger.info("Created the PrintWriter on the Response object");
try {
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:comp/env");
logger.info("Got environment context: "+envContext);
DataSource ds = (DataSource)envContext.lookup("jdbc/DataSource");
logger.info("Got DataSource: "+ds.toString());
con = ds.getConnection();
logger.info("Got Connection: "+con.toString() +"\n");
stmt = con.createStatement();
logger.info("Created the statement: " +stmt);
ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEE");
logger.info("Gto the result set: " +rs);
logger.info("Table EMP after SELECT:");
out.println("Your EMP table contains the following entries:<BR>");
out.println("<table>");
out.println("<tr>");
out.println("<th>Empno</th>");
out.println("<th>Name</th>");
out.println("<th>Job</th>");
out.println("<th>Manager</th>");
out.println("<th>Salary</th>");
out.println("<th>Commission</th>");
out.println("<th>Deptno</th>");
out.println("</tr>");
while (rs.next()) {
String emp = rs.getString("EMPNO");
String name = rs.getString("ENAME");
String job = rs.getString("JOB");
String mgr = rs.getString("MGR");
String sal = rs.getString("SAL");
String comm = rs.getString("COMM");
String dept = rs.getString("DEPTNO");
out.println("<tr>");
out.println("<td>"+emp+"</td>");
out.println("<td>"+name+"</td>");
out.println("<td>"+job+"</td>");
out.println("<td>"+mgr+"</td>");
out.println("<td>"+sal+"</td>");
out.println("<td>"+comm+"</td>");
out.println("<td>"+dept+"</td>");
out.println("</tr>");
logger.info(emp + " " + name + " " +job);
logger.info(" " + mgr + " " + dept);
}
out.println("</table>");
rs.close();
stmt.close();
con.close();
logger.trace("Trace");
logger.debug("Debug");
logger.info("Info");
logger.warn("Warn");
logger.error("Error");
}
catch(java.lang.Exception e) {
e.printStackTrace();
logger.error(e.getClass().getName());
logger.error(e.getMessage());
}
|
Listing 16 shows the dependencies declared for SLF4j in the Community Edition application deployment plan (geronimo-web.xml).
Listing 16. The geronimo-web.xml file with dependencies for SLF4j
<dependencies>
…………
…………
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.4.3</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.4.3</version>
<type>jar</type>
</dependency>
</dependencies>
|
Follow these steps to deploy and run the application:
- From the sample
download, unzip the application file. The war file is
Log4j-SLF4j-WEB.war.
-
Deploy the application.
<wasce_home>/bin>deploy --user system –-password manager deploy Log4j-SLF4j-WEB.war
-
Access the EMPDemo servlet at http://localhost:8080/Log4j-SLF4j-WEB/EMPDemo.
Listing 17 shows the log messages that display on the server console:
Listing 17. Server console messages
10:25:18,593 WARN [EMPDemo] Warn
10:25:18,593 ERROR [EMPDemo] Error
|
These messages display because; the ConsoleAppender’s log level is set to WARN in the server-log4j.properties file. Hence, only log messages with log level WARN or above are logged on the console. However, you can see that all the log messages are logged in the server.log file.
Configure SLF4j using Log4j at the application level
In this section, we configure SLF4j to use the Log4j configured at the application
level for the EMPDemo servlet. The servlet code in Listing 13 does not change.
However, the application ships with a log4j.properties file that replaces Log4j configuration at the server level. The EMPDemo servlet uses SLF4j API to log the messages. Listing 18 shows the log4j.properties file:
Listing 18. The log4j.properties file
log4j.logger.com.ibm.sample=debug,applog
log4j.appender.applog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.applog.File=C:/temp/applevellogging/SLF4j/java.log
log4j.appender.applog.layout=org.apache.log4j.PatternLayout
log4j.appender.applog.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}] %m%n
|
This log4j.properties file configures the Log4j service to use DailyRollingFileAppender to log messages to C:/temp/applevellogging/SLF4j/java.log file. It uses the Community Edition format used to log messages.
Listing 19 shows the relevant portion of the Community Edition application deployment
plan (geronimo-web.xml) for the application:
Listing 19. Community Edition application deployment plan
<dep:environment>
…………………
…………………
<dependencies>
…………………
…………………
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.4.3</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.4.3</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
<type>jar</type>
</dependency>
</dependencies>
<hidden-classes>
<filter>org.apache.log4j</filter>
</hidden-classes>
</dep:environment>
|
The deployment plan declares a dependency on the Log4j and SLF4j libraries, and hides the Log4j package from the parent classloader. Follow these steps to deploy the application.
-
Download the application and save it into a directory. The WAR file name is
Log4j-SLF4j-AppLevel-WEB.war.
-
Deploy the application.
<wasce_home>/bin>deploy –user system –password manager deploy Log4j-SLF4j-AppLevel-WEB.war.
-
Access the EMPDemo servlet at http://localhost:8080/Log4j-SLF4j-WEB/EMPDemo.
You can see that no messages are logged to either the server console or the server.log file. However, the applications creates the C:/temp/applevellogging/SLF4j/java.log file and logs the messages as configured.
|