log4j - 快速指南

log4j - 概述

log4j 是一个用 Java 编写的可靠、快速且灵活的日志记录框架 (API),根据 Apache 软件许可进行分发。

log4j 已移植到 C、C++、C#、Perl、Python、Ruby 和 Eiffel 语言。

log4j 在运行时可通过外部配置文件进行高度配置。它从优先级的角度来看待日志记录过程,并提供将日志记录信息定向到各种目的地(如数据库、文件、控制台、UNIX Syslog 等)的机制。

log4j 有三个主要组件:

  • loggers:负责捕获日志记录信息。

  • appenders:负责将日志记录信息发布到各种首选目的地。

  • layouts:负责以不同的样式格式化日志记录信息。

log4j 的历史

  • 于 1996 年初作为欧盟的跟踪 API 启动。 SEMPER(欧洲安全电子市场)项目。

  • 经过无数次的改进和多次改版,最初的 API 已发展成为 log4j,一种流行的 Java 日志记录包。

  • 该包根据 Apache 软件许可证分发,该许可证是经过开放源代码倡议认证的完全开放源代码许可证。

  • 最新的 log4j 版本,包括其完整源代码、类文件和文档,可在 http://logging.apache.org/log4j/ 找到。

log4j 功能

  • 它是线程安全的。

  • 它针对速度进行了优化。

  • 它基于命名记录器层次结构。

  • 它支持每个记录器有多个输出附加器。

  • 它支持国际化。

  • 它不限于预定义的一组设施。

  • 可以使用配置文件在运行时设置日志记录行为。

  • 它从一开始就被设计为处理 Java 异常。

  • 它使用多个级别,即 ALL、TRACE、DEBUG、INFO、WARN、ERROR 和 FATAL。

  • 可以通过扩展 Layout 类轻松更改日志输出的格式。

  • 可以通过 Appender 接口的实现来更改日志输出的目标以及写入策略。

  • 它是故障停止的。然而,尽管 log4j 确实努力确保交付,但它并不保证每个日志语句都将交付到目的地。

日志记录的优缺点

日志记录是软件开发的重要组成部分。编写良好的日志记录代码可快速调试、轻松维护和结构化存储应用程序的运行时信息。

日志记录也有其缺点。它会减慢应用程序的速度。如果太冗长,可能会导致滚动失明。为了缓解这些问题,log4j 被设计为可靠、快速和可扩展的。

由于日志记录很少是应用程序的主要焦点,因此 log4j API 力求简单易懂和使用。

log4j - 安装

log4j API 包根据 Apache 软件许可证分发,该许可证是经过开放源代码倡议认证的成熟开源许可证。

最新的 log4j 版本(包括完整源代码、类文件和文档)可在 http://logging.apache.org/log4j/ 找到。

要在您的系统上安装 log4j,请从指定的 URL 下载 apache-log4j-x.x.x.tar.gz,然后按照以下步骤操作。

步骤 1

将下载的文件解压缩并解压到 /usr/local/ 目录中,如下所示:

$ gunzip apache-log4j-1.2.15.tar.gz
$ tar -xvf apache-log4j-1.2.15.tar
apache-log4j-1.2.15/tests/input/
apache-log4j-1.2.15/tests/input/xml/
apache-log4j-1.2.15/tests/src/
apache-log4j-1.2.15/tests/src/java/
apache-log4j-1.2.15/tests/src/java/org/
.......................................

解压时,它会创建一个名为 apache-log4j-x.x.x 的目录层次结构,如下所示:

-rw-r--r--  1 root root   3565 2007-08-25 00:09 BUILD-INFO.txt
-rw-r--r--  1 root root   2607 2007-08-25 00:09 build.properties.sample
-rw-r--r--  1 root root  32619 2007-08-25 00:09 build.xml
drwxr-xr-x 14 root root   4096 2010-02-04 14:09 contribs
drwxr-xr-x  5 root root   4096 2010-02-04 14:09 examples
-rw-r--r--  1 root root   2752 2007-08-25 00:09 INSTALL
-rw-r--r--  1 root root   4787 2007-08-25 00:09 KEYS
-rw-r--r--  1 root root  11366 2007-08-25 00:09 LICENSE
-rw-r--r--  1 root root 391834 2007-08-25 00:29 log4j-1.2.15.jar
-rw-r--r--  1 root root    160 2007-08-25 00:09 NOTICE
-rwxr-xr-x  1 root root  10240 2007-08-25 00:27 NTEventLogAppender.dll
-rw-r--r--  1 root root  17780 2007-08-25 00:09 pom.xml
drwxr-xr-x  7 root root   4096 2007-08-25 00:13 site
drwxr-xr-x  8 root root   4096 2010-02-04 14:08 src
drwxr-xr-x  6 root root   4096 2010-02-04 14:09 tests

步骤 2

此步骤是可选的,取决于您要从 log4j 框架中使用哪些功能。如果您的机器上已经安装了以下软件包,那么就可以了,否则您需要安装它们才能使 log4j 工作。

步骤 3

现在您需要适当地设置 CLASSPATHPATH 变量。这里我们将仅为 log4j.x.x.x.jar 文件进行设置。

$ pwd
/usr/local/apache-log4j-1.2.15
$ export CLASSPATH=$CLASSPATH:/usr/local/apache-log4j-1.2.15/log4j-1.2.15.jar
$ export PATH=$PATH:/usr/local/apache-log4j-1.2.15/

log4j - 架构

log4j API 遵循分层架构,其中每一层提供不同的对象来执行不同的任务。这种分层架构使设计灵活且易于将来扩展。

log4j 框架有两种类型的对象。

  • 核心对象:这些是框架的必需对象。它们是使用框架所必需的。

  • 支持对象:这些是框架的可选对象。它们支持核心对象执行其他但重要的任务。

核心对象

核心对象包括以下类型的对象:

Logger 对象

顶层是提供 Logger 对象的 Logger。 Logger 对象负责捕获日志信息,这些信息存储在命名空间层次结构中。

布局对象

布局层提供用于以不同样式格式化日志信息的对象。它在发布日志信息之前为附加对象提供支持。

布局对象在以人性化和可重用的方式发布日志信息方面发挥着重要作用。

Appender 对象

这是一个提供 Appender 对象的较低层。 Appender 对象负责将日志信息发布到各种首选目标,例如数据库、文件、控制台、UNIX Syslog 等。

以下虚拟图显示了 log4J 框架的组件:

log4j Architecture

支持对象

log4j 框架中还有其他重要对象在日志框架中发挥着至关重要的作用:

Level 对象

Level 对象定义任何日志信息的粒度和优先级。 API 中定义了七个级别的日志记录:OFF、DEBUG、INFO、ERROR、WARN、FATAL 和 ALL。

Filter 对象

Filter 对象用于分析日志记录信息并进一步决定是否应记录该信息。

Appender 对象可以有多个与其关联的 Filter 对象。如果将日志记录信息传递给特定的 Appender 对象,则与该 Appender 关联的所有 Filter 对象都需要批准该日志记录信息,然后才能将其发布到附加的目标。

ObjectRenderer

ObjectRenderer 对象专门用于提供传递给日志记录框架的不同对象的字符串表示形式。Layout 对象使用此对象来准备最终的日志记录信息。

LogManager

LogManager 对象管理日志记录框架。它负责从系统范围的配置文件或配置类中读取初始配置参数。

log4j - 配置

上一章介绍了 log4j 的核心组件。本章介绍如何使用配置文件配置核心组件。配置 log4j 涉及在配置文件中分配级别、定义 Appender 和指定 Layout 对象。

log4j.properties 文件是一个 log4j 配置文件,它将属性保存在键值对中。默认情况下,LogManager 在 CLASSPATH 中查找名为 log4j.properties 的文件。

  • 根记录器的级别定义为 DEBUGDEBUG 将名为 X 的附加器附加到它。

  • 将名为 X 的附加器设置为有效附加器。

  • 设置附加器 X 的布局。

log4j.properties 语法:

以下是附加器 X 的 log4j.properties 文件的语法:

# 使用附加器 X 定义根记录器
log4j.rootLogger = DEBUG, X

# 将名为 X 的附加器设置为文件附加器
log4j.appender.X=org.apache.log4j.FileAppender

# 定义 X 的布局appender
log4j.appender.X.layout=org.apache.log4j.PatternLayout
log4j.appender.X.layout.conversionPattern=%m%n

log4j.properties 示例

使用上述语法,我们在 log4j.properties 文件中定义以下内容:

  • 根记录器的级别定义为 DEBUGDEBUG 附加器将其命名为 FILE

  • 附加器 FILE 定义为 org.apache.log4j.FileAppender。它会写入位于 log 目录中名为 log.out 的文件。

  • 定义的布局模式为 %m%n,这意味着打印的日志消息后面会跟着一个换行符。

# 使用附加文件定义根记录器
log4j.rootLogger = DEBUG, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out

# 定义文件附加器的布局
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

需要注意的是log4j 支持 UNIX 样式的变量替换,例如 ${variableName}。

调试级别

我们对两个附加程序都使用了 DEBUG。所有可能的选项如下:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • ALL

本教程后面将解释这些级别。

Appenders

Apache log4j 提供 Appender 对象,主要负责将日志消息打印到不同的目标,例如控制台、文件、套接字、NT 事件日志等。

每个 Appender 对象都有与之关联的不同属性,这些属性指示该对象的行为。

属性 描述
layout Appender 使用 Layout 对象及其关联的转换模式来格式化日志信息。
target 目标可能是控制台、文件或其他项目,具体取决于附加器。
level 需要级别来控制日志消息的过滤。
threshold Appender 可以具有与其关联的阈值级别,与记录器级别无关。Appender 会忽略任何级别低于阈值级别的日志消息。
filter Filter 对象可以分析级别匹配之外的日志信息,并决定日志请求是否应由特定 Appender 处理或忽略。

我们可以通过在配置文件中包含以下设置,使用以下方法将 Appender 对象添加到 Logger:

log4j.logger.[logger-name]=level, appender1,appender..n

您可以按照如下方式以 XML 格式编写相同的配置:

<logger name="com.apress.logging.log4j" additivity="false">
   <appender-ref ref="appender1"/>
   <appender-ref ref="appender2"/>
</logger>

如果您愿意在程序中添加 Appender 对象,则可以使用以下方法:

public void addAppender(Appender appender);

addAppender() 方法将 Appender 添加到 Logger 对象。如示例配置所示,可以将多个 Appender 对象添加到以逗号分隔的列表中的记录器,每个对象将日志信息打印到不同的目的地。

在上面的示例中,我们仅使用了一个附加器 FileAppender。所有可能的附加器选项如下:

  • AppenderSkeleton
  • AsyncAppender
  • ConsoleAppender
  • DailyRollingFileAppender
  • ExternallyRolledFileAppender
  • FileAppender
  • JDBCAppender
  • JMSAppender
  • LF5Appender
  • NTEventLogAppender
  • NullAppender
  • RollingFileAppender
  • SMTPAppender
  • SocketAppender
  • SocketHubAppender
  • SyslogAppender
  • TelnetAppender
  • WriterAppender

我们将在登录文件中介绍 FileAppender,在登录数据库中介绍 JDBC Appender。

布局

我们已将 PatternLayout 与附加器结合使用。所有可能的选项是:

  • DateLayout
  • HTMLLayout
  • PatternLayout
  • SimpleLayout
  • XMLLayout

使用 HTMLLayout 和 XMLLayout,您可以生成 HTML 和 XML 格式的日志。

布局格式

您将在章节:日志格式中学习如何格式化日志消息。

log4j - 示例程序

我们已经了解了如何创建配置文件。本章介绍如何生成调试消息并将其记录在简单的文本文件中。

以下是为我们的示例创建的简单配置文件。我们再修改一下:

  • 根记录器的级别定义为DEBUG,并将名为FILE的附加器附加到它。

  • 附加器FILE定义为org.apache.log4j.FileAppender,并写入位于log目录中名为log.out的文件。

  • 定义的布局模式为%m%n,这意味着打印的日志消息后面会跟着一个换行符。

log4j.properties文件的内容如下−

# 定义带有附加器文件的根记录器
log = /usr/home/log4j
log4j.rootLogger = DEBUG, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out

# 定义文件附加器的布局
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

在 Java 程序中使用 log4j

以下 Java 类是一个非常简单的示例,它初始化 Java 应用程序的 log4j 日志记录库,然后使用它。

import org.apache.log4j.Logger;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class log4jExample{

   /* 获取要打印的实际类名 */
   static Logger log = Logger.getLogger(log4jExample.class.getName());
   
   public static void main(String[] args)throws IOException,SQLException{
      log.debug("Hello this is a debug message");
      log.info("Hello this is an info message");
   }
}

编译并执行

以下是编译并运行上述程序的步骤。在继续编译和执行之前,请确保已正确设置 PATHCLASSPATH

所有库都应在 CLASSPATH 中可用,并且您的 log4j.properties 文件应在 PATH 中可用。按照下面给出的步骤 −

  • 如上所示创建 log4j.properties。

  • 如上所示创建 log4jExample.java 并编译它。

  • 执行 log4jExample 二进制文件以运行该程序。

您将在 /usr/home/log4j/log.out 文件中得到以下结果 −

Hello this is a debug message
Hello this is an info message

log4j - 日志记录方法

Logger 类提供了多种方法来处理日志记录活动。Logger 类不允许我们实例化新的 Logger 实例,但它提供了两种静态方法来获取 Logger 对象 −

  • public static Logger getRootLogger();
  • public static Logger getLogger(String name);

两种方法中的第一个返回应用程序实例的根记录器,并且它没有名称。

任何其他命名的 Logger 对象实例都通过第二种方法通过传递记录器的名称来获取。记录器的名称可以是任何可以传递的字符串,通常是类或包名称,就像我们在上一章中使用的一样,下面会提到 −

static Logger log = Logger.getLogger(log4jExample.class.getName());

记录方法

一旦我们获得命名记录器的实例,我们就可以使用记录器的几种方法来记录消息。 Logger 类具有以下用于打印日志信息的方法。

# 方法和说明
1 public void debug(Object message)

它以 Level.DEBUG 级别打印消息。

2 public void error(Object message)

它以 Level.ERROR 级别打印消息。

3 public void fatal(Object message)

它以 Level.DEBUG 级别打印消息。

3 public void fatal(Object message)

它以 Level.ERROR 级别打印消息Level.FATAL。

4 public void info(Object message)

它以 Level.INFO 级别打印消息。

5 public void warn(Object message)

它以 Level.WARN 级别打印消息。

6 public void trace(Object message)

它以 Level.TRACE 级别打印消息。

所有级别均在 org.apache.log4j.Level 类中定义,并且上述任何方法都可以按如下方式调用 −

import org.apache.log4j.Logger;

public class LogClass {
   private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
   
   public static void main(String[] args) {
   
      log.trace("Trace Message!");
      log.debug("Debug Message!");
      log.info("Info Message!");
      log.warn("Warn Message!");
      log.error("Error Message!");
      log.fatal("Fatal Message!");
   }
}

当你编译并运行 LogClass 程序时,它将产生以下结果 −

Debug Message!
Info Message!
Warn Message!
Error Message!
Fatal Message!

所有调试消息在与级别结合使用时都更有意义。我们将在下一章中介绍级别,然后您将很好地理解如何将这些方法与不同级别的调试结合使用。

log4j - 日志记录级别

org.apache.log4j.Level 级别。您还可以通过对 Level 类进行子类化来定义自定义级别。

级别 说明
ALL 所有级别,包括自定义级别。
DEBUG 指定对调试应用程序最有用的细粒度信息事件。
INFO 指定在粗粒度级别突出显示应用程序进度的信息消息。
WARN 指定潜在有害情况。
ERROR 指定可能仍允许应用程序继续运行的错误事件。
FATAL 指定可能导致应用程序中止的非常严重的错误事件。
OFF 最高级别,旨在关闭日志记录。
TRACE 指定比 DEBUG 更细粒度的信息事件。

级别如何工作?

如果 p,则在级别为 q 的记录器中,级别为 p 的日志请求启用 >= q。此规则是 log4j 的核心。它假设级别是有序的。对于标准级别,我们有 ALL < DEBUG < INFO < WARN < ERROR < FATAL < OFF。

以下示例显示了如何过滤所有 DEBUG 和 INFO 消息。此程序使用记录器方法 setLevel(Level.X) 来设置所需的日志记录级别:

此示例将打印除 Debug 和 Info 之外的所有消息:

import org.apache.log4j.*;

public class LogClass {
   private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
   
   public static void main(String[] args) {
      log.setLevel(Level.WARN);

      log.trace("Trace Message!");
      log.debug("Debug Message!");
      log.info("Info Message!");
      log.warn("Warn Message!");
      log.error("Error Message!");
      log.fatal("Fatal Message!");
   }
}

当您编译并运行 LogClass 程序时,它将生成以下结果 −

Warn Message!
Error Message!
Fatal Message!

使用配置文件设置级别

log4j 为您提供基于配置文件的级别设置,当您想要更改调试级别时,您无需更改源代码。

以下是一个示例配置文件,它将执行与我们在上述示例中使用 log.setLevel(Level.WARN) 方法执行的相同任务。

# 使用附加文件定义根记录器
log = /usr/home/log4j
log4j.rootLogger = WARN, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out

# 定义文件布局appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

现在让我们使用以下程序 −

import org.apache.log4j.*;

public class LogClass {

   private static org.apache.log4j.Logger log = Logger.getLogger(LogClass.class);
   
   public static void main(String[] args) {
   
      log.trace("Trace Message!");
      log.debug("Debug Message!");
      log.info("Info Message!");
      log.warn("Warn Message!");
      log.error("Error Message!");
      log.fatal("Fatal Message!");
   }
}

现在编译并运行上述程序,您将在 /usr/home/log4j/log.out 文件中得到以下结果−

Warn Message!
Error Message!
Fatal Message!

log4j - 日志格式

Apache log4j 提供各种 Layout 对象,每个对象都可以根据各种布局格式化日志数据。还可以创建一个以特定于应用程序的方式格式化日志数据的 Layout 对象。

所有 Layout 对象都从 Appender 对象接收 LoggingEvent 对象。然后,Layout 对象从 LoggingEvent 中检索消息参数并应用适当的 ObjectRenderer 来获取消息的字符串表示形式。

布局类型

层次结构中的顶级类是抽象类 org.apache.log4j.Layout。这是 log4j API 中所有其他 Layout 类的基类。

Layout 类在应用程序中定义为抽象,我们从不直接使用此类;相反,我们使用其子类,如下所示:

布局方法

此类提供了所有其他布局对象中所有常见操作的骨架实现,并声明了两个抽象方法。

Sr.No. 方法 &描述
1 public abstract boolean ignoresThrowable()

它指示日志记录信息是否处理作为日志记录事件的一部分传递给它的任何 java.lang.Throwable 对象。如果 Layout 对象处理 Throwable 对象,则 Layout 对象不会忽略它,并返回 false。

2 public abstract String format(LoggingEvent event)

各个布局子类实现此方法以实现特定于布局的格式。

除了这些抽象方法之外,Layout 类还为下面列出的方法提供了具体的实现:

Sr.No. 方法 &描述
1 public String getContentType()

返回Layout对象使用的内容类型。基类返回text/plain作为默认内容类型。

2 public String getFooter()

指定日志消息的页脚信息。

3 public String getHeader()

指定日志消息的标题信息。

每个子类都可以通过重写这些方法的具体实现来返回特定于类的信息。

log4j - 文件中的日志记录

要将日志记录信息写入文件,您必须使用 org.apache.log4j.FileAppender

FileAppender 配置

FileAppender 具有以下可配置参数:

属性 描述
immediateFlush 此标志默认设置为 true,这意味着每次执行附加操作时都会刷新到文件的输出流。
编码 可以使用任何字符编码。默认情况下,它是特定于平台的编码方案。
threshold 此附加器的阈值级别。
Filename 日志文件的名称。
fileAppend 默认情况下设置为 true,这意味着日志信息将附加到同一文件的末尾。
bufferedIO 此标志表示我们是否需要启用缓冲写入。默认情况下,它设置为 false。
bufferSize 如果启用了缓冲 I/O,则它表示缓冲区大小。默认情况下,它设置为 8kb。

以下是 FileAppender 的示例配置文件 log4j.properties

# 定义带有附加器文件的根记录器
log4j.rootLogger = DEBUG, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.FileAppender

# 设置文件的名称
log4j.appender.FILE.File=${log}/log.out

# 将立即刷新设置为 true(默认)
log4j.appender.FILE.ImmediateFlush=true

# 将阈值设置为调试模式
log4j.appender.FILE.Threshold=debug

# 将附加设置为 false,覆盖
log4j.appender.FILE.Append=false

# 定义布局文件附加器
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

如果您希望拥有一个与上述 log4j.properties 文件等效的 XML 配置文件,则内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

<appender name="FILE" class="org.apache.log4j.FileAppender">

   <param name="file" value="${log}/log.out"/>
   <param name="immediateFlush" value="true"/>
   <param name="threshold" value="debug"/>
   <param name="append" value="false"/>
   
   <layout class="org.apache.log4j.PatternLayout">
      <param name="conversionPattern" value="%m%n"/>
   </layout>
</appender>

<logger name="log4j.rootLogger" additivity="false">
   <level value="DEBUG"/>
   <appender-ref ref="FILE"/>
</logger>

</log4j:configuration>

您可以使用上述配置尝试 log4j - 示例程序

在多个文件中记录日志

您可能出于某些原因想要将日志消息写入多个文件,例如,如果文件大小达到某个阈值。

要将日志信息写入多个文件,您必须使用 org.apache.log4j.RollingFileAppender 类,该类扩展了 FileAppender 类并继承了其所有属性。

除了上面提到的 FileAppender 参数外,我们还有以下可配置参数 −

属性 描述
maxFileSize 这是文件的临界大小,超过该大小文件将被滚动。默认值为 10 MB。
maxBackupIndex 此属性表示要创建的备份文件的数量。默认值为 1。

以下是 RollingFileAppender 的示例配置文件 log4j.properties

# 使用附加文件定义根记录器
log4j.rootLogger = DEBUG, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.RollingFileAppender

# 设置文件的名称
log4j.appender.FILE.File=${log}/log.out

# 将立即刷新设置为 true(默认)
log4j.appender.FILE.ImmediateFlush=true

# 将阈值设置为调试模式
log4j.appender.FILE.Threshold=debug

# 将附加设置为 false,不应覆盖
log4j.appender.FILE.Append=true

#设置滚动前的最大文件大小
log4j.appender.FILE.MaxFileSize=5MB

# 设置备份索引
log4j.appender.FILE.MaxBackupIndex=2

# 定义文件附加器的布局
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

如果您希望拥有 XML 配置文件,您可以生成与初始部分中提到的相同的文件,并仅添加与 RollingFileAppender 相关的附加参数。

此示例配置表明每个日志文件的最大允许大小为 5 MB。超过最大大小后,将创建一个新的日志文件。由于 maxBackupIndex 定义为 2,一旦第二个日志文件达到最大大小,第一个日志文件将被删除,此后,所有日志信息将回滚到第一个日志文件。

您可以尝试使用上述配置的 log4j - 示例程序

每日日志文件生成

可能需要每天生成日志文件以保持日志信息的清晰记录。

要每天将日志信息写入文件,您必须使用 org.apache.log4j.DailyRollingFileAppender 类,该类扩展了 FileAppender 类并继承了其所有属性。

只有一个重要的可配置参数除了上面提到的 FileAppender 之外:

属性 描述
DatePattern 这表示何时滚动文件以及要遵循的命名约定。默认情况下,滚动在每天午夜执行。

DatePattern 使用以下模式之一控制滚动计划:

DatePattern 描述
'.' yyyy-MM 在每个月末和下个月初滚动。
'.' yyyy-MM-dd 每天午夜滚动。这是默认值。
'.' yyyy-MM-dd-a 在每天中午和午夜滚动。
'.' yyyy-MM-dd-HH 每小时开始时滚动。
'.' yyyy-MM-dd-HH-mm 每分钟滚动一次。
'.' yyyy-ww 根据语言环境在每周的第一天滚动。

以下是示例配置文件 log4j.properties,用于生成在每天中午和午夜滚动的日志文件。

# 使用附加文件定义根记录器
log4j.rootLogger = DEBUG, FILE

# 定义文件附加器
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender

# 设置文件的名称
log4j.appender.FILE.File=${log}/log.out

# 将立即刷新设置为 true(默认)
log4j.appender.FILE.ImmediateFlush=true

# 设置要调试的阈值模式
log4j.appender.FILE.Threshold=debug

# 将附加设置为 false,不应覆盖
log4j.appender.FILE.Append=true

# 设置 DatePattern
log4j.appender.FILE.DatePattern='.' yyyy-MM-dd-a

# 定义文件附加器的布局
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

如果您希望拥有 XML 配置文件,您可以生成与初始部分中提到的相同的文件,并仅添加与 DailyRollingFileAppender 相关的附加参数。

您可以使用上述配置尝试 log4j - Sample Program

log4j - 数据库中的日志记录

log4j API 提供了 org.apache.log4j.jdbc.JDBCAppender 对象,该对象可以将日志记录信息放入指定的数据库中。

JDBCAppender 配置

属性 描述
bufferSize 设置缓冲区大小。默认大小为 1。
driver 将驱动程序类设置为指定的字符串。如果未指定驱动程序类,则默认为 sun.jdbc.odbc.JdbcOdbcDriver
layout 设置要使用的布局。默认布局为 org.apache.log4j.PatternLayout
password 设置数据库密码。
sql 指定每次发生日志记录事件时要执行的 SQL 语句。这可以是 INSERT、UPDATE 或 DELETE。
URL 设置 JDBC URL。
user 设置数据库用户名。

日志表配置

在开始使用基于 JDBC 的日志记录之前,您应该创建一个表来维护所有日志信息。以下是创建 LOGS 表的 SQL 语句 −

CREATE TABLE LOGS
   (USER_ID VARCHAR(20)    NOT NULL,
    DATED   DATE           NOT NULL,
    LOGGER  VARCHAR(50)    NOT NULL,
    LEVEL   VARCHAR(10)    NOT NULL,
    MESSAGE VARCHAR(1000)  NOT NULL
   );

示例配置文件

以下是 JDBCAppender 的示例配置文件 log4j.properties,它将用于将消息记录到 LOGS 表中。

# 使用附加器文件定义根记录器
log4j.rootLogger = DEBUG, DB

# 定义 DB 附加器
log4j.appender.DB=org.apache.log4j.jdbc.JDBCAppender

# 设置 JDBC URL
log4j.appender.DB.URL=jdbc:mysql://localhost/DBNAME

# 设置数据库驱动程序
log4j.appender.DB.driver=com.mysql.jdbc.Driver

# 设置数据库用户名和密码
log4j.appender.DB.user=user_name
log4j.appender.DB.password=password

# 设置要执行的 SQL 语句。
log4j.appender.DB.sql=INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m')

# 定义文件附加器的布局
log4j.appender.DB.layout=org.apache.log4j.PatternLayout

对于 MySQL 数据库,您必须使用实际的 DBNAME、用户 ID 和密码,其中您已创建了 LOGS 表。SQL 语句将使用表名 LOGS 和要输入到表中的值来执行 INSERT 语句。

JDBCAppender 不需要明确定义布局。相反,传递给它的 SQL 语句使用 PatternLayout。

如果您希望拥有一个与上述 log4j.properties 文件等效的 XML 配置文件,那么这里是内容 −

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

<appender name="DB" class="org.apache.log4j.jdbc.JDBCAppender">
   <param name="url" value="jdbc:mysql://localhost/DBNAME"/>
   <param name="driver" value="com.mysql.jdbc.Driver"/>
   <param name="user" value="user_id"/>
   <param name="password" value="password"/>
   <param name="sql" value="INSERT INTO LOGS VALUES('%x','%d','%C','%p','%m')"/>
   
   <layout class="org.apache.log4j.PatternLayout">
   </layout>
</appender>

<logger name="log4j.rootLogger" additivity="false">
   <level value="DEBUG"/>
   <appender-ref ref="DB"/>
</logger>

</log4j:configuration>

示例程序

以下 Java 类是一个非常简单的示例,它初始化 Java 应用程序的 Log4J 日志库,然后使用该库。

import org.apache.log4j.Logger;
import java.sql.*;
import java.io.*;
import java.util.*;

public class log4jExample{
   /* 获取要打印的实际类名 */
   static Logger log = Logger.getLogger(log4jExample.class.getName());
   
   public static void main(String[] args)throws IOException,SQLException{
      log.debug("Debug");
      log.info("Info");
   }
}

编译并执行

以下是编译和运行上述程序的步骤。在继续编译和执行之前,请确保已正确设置 PATHCLASSPATH

所有库都应在 CLASSPATH 中可用,并且 log4j.properties 文件应在 PATH 中可用。按照给定的步骤 −

  • 如上所示创建 log4j.properties。
  • 如上所示创建 log4jExample.java 并对其进行编译。
  • 执行 log4jExample 二进制文件以运行该程序。

现在检查 DBNAME 数据库中的 LOGS 表,您将找到以下条目−

mysql >  select * from LOGS;
+---------+------------+--------------+-------+---------+
| USER_ID | DATED      | LOGGER       | LEVEL | MESSAGE |
+---------+------------+--------------+-------+---------+
|         | 2010-05-13 | log4jExample | DEBUG | Debug   |
|         | 2010-05-13 | log4jExample | INFO  | Info    |
+---------+------------+--------------+-------+---------+
2 rows in set (0.00 sec)

注意 − 此处 x 用于输出与生成日志事件的线程关联的嵌套诊断上下文 (NDC)。我们使用 NDC 来区分处理多个客户端的服务器端组件中的客户端。有关此内容的更多信息,请查看 Log4J 手册。