在 Community Edition 中使用 SLF4J
Simple Logging Facade for Java (SLF4J) 作为各种日志记录 API 的简单 Facade 使用,可用于在部署时插入所需的实现。SLF4j 并没有创建另一个日志记录框架,而是让应用程序使用标准 API,在部署时插入实际的日志记录实现。
SLF4j 支持多个日志记录系统,如 NOP、Simple、Log4j V1.2、java.util.logging、JCL 和 logback。SLF4j 分发通过多个 JAR 文件提供:
-
slf4j-nop.jar
-
slf4j-simple.jar
-
slf4j-log4j12.jar
-
slf4j-log4j13.jar
-
slf4j-jdk14.jar
-
slf4j-jcl.jar.
其中的每个 jar 文件都在编译时硬连接,只使用一个实现。所有 SLF4j 的绑定都依赖于 slf4j-api.jar,此文件必须在类路径中,绑定才能正常工作。另外,还提供了迁移路径,以便应用程序通过桥接模块使用具体的日志记录实现。Community Edition 提供了可在应用程序中使用的以下库:
-
slf4j-api-1.4.3.jar
-
slf4j-log4j12-1.4.3.jar
-
jcl104-over-slf4j-1.4.3.jar
在此部分,我们将说明如何采用以下方式使用 SLF4j。
-
配置 SLF4j 以使用服务器 Log4j 配置
-
配置 SLF4j 以在应用程序级别使用 Log4j
配置 SLF4j 以使用服务器 Log4j 配置
在此部分,我们将在 EMPDemo Servlet 中使用 SLF4j API 替代 Log4j API。不过,它在服务器级别使用 Log4j 实现作为具体实现。清单 15 显示了这个 Servlet 的代码:
清单 15. 使用 SLF4j API 的 EMPDemo Servlet
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());
}
|
清单 16 显示了 Community Edition 应用程序部署计划 (geronimo-web.xml) 中为 SLF4j 声明的依赖关系。
清单 16. 包含 SLF4j 的依赖关系的 geronimo-web.xml 文件
<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>
|
请遵循以下步骤操作,以部署和运行应用程序:
- 在下载的示例中,解压缩应用程序文件。war 文件为
Log4j-SLF4j-WEB.war。
-
部署应用程序。
<wasce_home>/bin>deploy --user system –-password manager deploy Log4j-SLF4j-WEB.war
-
通过
http://localhost:8080/Log4j-SLF4j-WEB/EMPDemo 访问 EMPDemo Servlet。
清单 17 显示了在服务器控制台上显示的日志消息:
清单 17. 服务器控制台消息
10:25:18,593 WARN [EMPDemo] Warn
10:25:18,593 ERROR [EMPDemo] Error
|
之所以显示这些消息,是因为 ConsoleAppender 的日志级别在 server-log4j.properties 文件中设置为 WARN。因此,只有日志级别为 WARN 或更高的消息记录在控制台中。不过,您可以看到,所有日志消息都记录在 server.log 文件中。
配置 SLF4j 以在应用程序级别使用 Log4j
在此部分,我们将配置 SLF4j 在 EMPDemo Servlet 的应用程序级别使用所配置的 Log4j。并未更改清单 13 中的 Servlet 代码。不过,应用程序带一个 log4j.properties 文件,替代了服务器级别的 Log4j 配置。EMPDemo Servlet 使用 SLF4j API 记录消息。清单 18 显示了 log4j.properties 文件:
清单 18. log4j.properties 文件
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
|
这个 log4j.properties 文件配置 Log4j 服务使用 DailyRollingFileAppender 将消息记录到 C:/temp/applevellogging/SLF4j/java.log 文件。它使用记录消息的 Community Edition 格式。
清单 19 显示了应用程序的 Community Edition 应用程序部署计划 (geronimo-web.xml) 中的相关部分:
清单 19. Community Edition 应用程序部署计划
<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>
|
部署计划声明对 Log4j 和 SLF4j 库的依赖关系,并将 Log4j 包从父类加载器隐藏。请遵循以下步骤来部署此应用程序。
-
下载应用程序,将其保存到目录中。WAR 文件名为
Log4j-SLF4j-AppLevel-WEB.war。
-
部署应用程序。
<wasce_home>/bin>deploy –user system –password manager deploy Log4j-SLF4j-AppLevel-WEB.war.
-
通过
http://localhost:8080/Log4j-SLF4j-WEB/EMPDemo 访问 EMPDemo Servlet。
您可以发现服务器控制台或 server.log 文件中都没有记录消息。不过,应用程序会创建 C:/temp/applevellogging/SLF4j/java.log 文件并按照所配置的方式记录消息。
|