Java Servlet Log4j 教程展示了如何在 Java Servlet 中使用 Log4j 进行日志记录。本教程涵盖 Log4j 版本 2。
Java 小服务程序
Servlet是一个 Java 类,它响应特定类型的网络请求——最常见的是 HTTP 请求。Java servlet 用于创建 Web 应用程序。它们在 Tomcat 或 Jetty 等 servlet 容器中运行。现代 Java Web 开发使用构建在 servlet 之上的框架。
Log4j
Apache Log4j 是一个基于 Java 的日志记录实用程序。它是 Apache 软件基金会的一个项目。Log4j 可以通过 Java 代码或在配置文件中进行配置。配置文件可以用 XML、JSON、YAML 或属性文件格式编写。
Log4j 具有三个主要组件:记录器、附加程序和布局。记录器被命名为捕获捕获日志消息并将它们发送到附加程序的目标。Appender 将日志消息传递到它们的目的地,例如文件或控制台。布局用于定义日志消息的格式。
Java servlet 日志记录示例
以下 Web 应用程序正在使用 Log4j 进行日志记录。在 Servlet 3.0+ 应用程序中,Log4j 开箱即用。它在应用程序部署时自动启动,并在应用程序取消部署时关闭。
$ tree
.
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── zetcode
│ ├── service
│ │ └── MyService.java
│ └── web
│ └── MyServlet.java
├── resources
│ └── log4j2.xml
└── webapp
├── index.html
├── META-INF
│ └── context.xml
└── WEB-INF
这是项目结构。Log4j 配置文件放在该src/main/resources/
目录下。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>JavaServletLog4j</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>JavaServletLog4j</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-web</artifactId>
<version>2.8.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
这是 Maven POM 文件。我们有两个工件:javax.servlet-api
用于 servlet 和log4j-web
用于在 Web 应用程序中使用 Log4j 进行日志记录。maven-war-plugin
负责收集 Web 应用程序的所有工件依赖项、类和资源,并将它们打包到 Web 应用程序存档 (WAR) 中 。
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JavaServletLog4j"/>
在 Tomcatcontext.xml
文件中,我们定义了上下文路径。它是 Web 应用程序的名称。
<?xml version="1.0" encoding="utf-8"?>
<Configuration status="info">
<Properties>
<Property name="logdir">/home/janbodnar/tmp</Property>
<Property name="layout">%d [%t] %-5p %c- %m%n</Property>
</Properties>
<Appenders>
<RollingFile name="LOCALHOST"
fileName="${logdir}/localhost.log"
filePattern="${logdir}/localhost.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
</Appenders>
<Loggers>
<Logger name="com.zetcode"
level="info" additivity="false">
<AppenderRef ref="LOCALHOST" />
</Logger>
<Root level="error">
</Root>
</Loggers>
</Configuration>
Log4j 在log4j2.xml
. 在我们的示例中,我们选择了 XML 文件格式。
<Properties>
<Property name="logdir">/home/janbodnar/tmp</Property>
<Property name="layout">%d [%t] %-5p %c - %m%n</Property>
</Properties>
在Properties
标签中,我们设置了日志目录和布局。布局定义了日志的格式。
模式布局由转换说明符组成。每个说明符都以百分号开头,后跟可选的格式修饰符和强制转换字符。输出记录事件的%d
日期。%t
输出生成日志事件的线程的名称。输出日志事件的%-5p
级别,其中级别名称至少包含五个字符,并且字符左对齐。输出发布日志事件的记录器的%c
名称。%m
打印与日志事件关联的应用程序消息,并且是%n
平台相关的行分隔符或字符。
<Appenders>
...
</Appenders>
附加程序是定义日志消息保存位置的对象。有几个可能的目的地,包括控制台、文件、数据库表或套接字。
<RollingFile name="LOCALHOST"
fileName="${logdir}/localhost.log"
filePattern="${logdir}/localhost.%d{yyyy-MM-dd}-%i.log">
<PatternLayout pattern="${layout}" />
...
<DefaultRolloverStrategy max="10" />
</RollingFile>
我们设置日志文件的位置。我们使用滚动文件附加程序,它会自动滚动或归档当前日志文件并恢复登录新文件。设置日志消息的PatternLayout
布局。DefaultRolloverStrategy
如果档案数量达到十个,则删除较旧的档案 。
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="1 MB" />
</Policies>
触发策略在Policies
标签中定义。它们控制发生翻转的条件。这里我们使用两个策略:TimeBasedTriggeringPolicy
和SizeBasedTriggeringPolicy
。根据TimeBasedTriggeringPolicy
最具体的日期和时间模式开始翻转;在我们的例子中,每小时。如果日志文件的SizeBasedTriggeringPolicy
大小达到 1 MB,则开始翻转。
<Loggers>
<Logger name="com.zetcode"
level="info" additivity="false">
<AppenderRef ref="LOCALHOST" />
</Logger>
<Root level="error">
</Root>
</Loggers>
在Loggers
标签中我们定义了记录器。它们被命名为日志消息目的地。每个记录器可以配置不同级别的记录。我们定义了一个具有信息记录级别的记录器。我们将之前定义的滚动文件附加程序附加到此记录器。设置为 false 时,additivity
日志消息不会传播到它们的祖先。
package com.zetcode.web;
import com.zetcode.service.MyService;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {
final static Logger logger = LogManager.getLogger(MyService.class);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
logger.info("MyServlet's doGet() called");
MyService service = new MyService();
service.doWork();
response.setContentType("text/plain;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("MyServlet called");
}
}
这是MyServlet
小服务程序。它调用服务方法并将文本数据发送回客户端。
final static Logger logger = LogManager.getLogger(MyService.class);
我们从LogManager
.
logger.info("MyServlet's doGet() called");
我们记录信息级别的消息。
MyService service = new MyService();
service.doWork();
我们称之为虚拟服务方法。
PrintWriter out = response.getWriter();
out.print("MyServlet called");
我们向客户端发送文本数据。
package com.zetcode.service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class MyService {
final static Logger logger = LogManager.getLogger(MyService.class);
public void doWork() {
logger.info("MyService's doWork() called");
}
}
该MyService's
doWork()
方法记录信息级消息。
index.html
<!DOCTYPE html>
<html>
<head>
<title>Home Page</title>
<meta charset="UTF-8">
</head>
<body>
<a href="MyServlet">Call Servlet</a>
</body>
</html>
主页包含一个调用MyServlet
.
$ cat localhost.log
2017-11-14 16:50:30,157 [http-nio-8084-exec-5] INFO com.zetcode.service.MyService- MyServlet's doGet() called
2017-11-14 16:50:31,044 [http-nio-8084-exec-5] INFO com.zetcode.service.MyService- MyService's doWork() called
这是记录消息的示例输出。
在本教程中,我们在 Java Web 应用程序中使用 Log4j 完成了一些日志记录。