什么是log4j?
- log4j 是一个帮助程序员将日志语句输出到各种输出目标的工具。
- log4j 包的设计使得日志语句可以保留在已发布的代码中,而不会产生高性能成本。
- log4j 使用
分层记录器
可以有选择地控制以任意粒度输出哪些日志语句。 - log4j 的设计考虑了三个目标:
可靠性
、速度
和灵活性
。
log4j是一个可靠的日志系统吗?
不是。log4j 不可靠。它是一种尽力而为的
故障停止记录系统。
通过失败停止,log4j 不会在运行时抛出意外的异常,从而可能导致应用程序崩溃。
此外,当 log4j 的指定输出流未打开,不可写或变满时,log4j 将不会恢复为System.out
或 System.err
。这样可以避免因为日志记录失败而覆盖用户终端而损坏其他工作程序。但是,log4j 将向System.err
输出单个消息,指示无法执行日志记录。
log4j有什么特点?
- log4j 针对
速度
进行了优化。 - log4j 基于命名的记录器层次结构。
- log4j 是失败停止,但并不保证每个日志语句都将传递到其目的地。
- log4j 是
线程安全
的,Log4j 组件设计用于大量多线程系统。 - log4j 配置文件可以是
属性文件
或XML
格式。 - log4j 旨在从一开始就处理 Java Exceptions。
- log4j 可以将其输出定向到
文件
、控制台
、java.io.OutputStream
、java.io.Writer
、使用 TCP 的远程服务器
、远程 Unix Syslog 守护程序
、使用 JMS 的远程侦听器
、NT EventLog
、电子邮件
。 - log4j 使用 6 个级别:即
TRACE
,DEBUG
,INFO
,WARN
,ERROR
和FATAL
。等级:DEBUG < INFO < WARN < ERROR < FATAL
。 - 通过扩展
Layout类
可以轻松更改日志输出的格式。 - 通过
Appender接口的实现
来更改日志输出的目标以及写入策略 。 - log4j 支持每个记录器输出多个
appender
。 - log4j 支持国际化。
是否有使用log4j的示例代码?
请参阅 examples / 目录。
日志输出是什么样的?
可以通过多种方式自定义日志输出。此外,可以通过实现自己的布局完全覆盖输出格式。以下是使用PatternLayout
的示例输出,其转换模式为:%r [%t]%-5p%c {2}%x - %m%n
176 [main] INFO examples.Sort - 以相反的顺序填充2个元素的数组。
225 [main] INFO examples.SortAlgo - 输入排序方法。
262 [main] DEBUG SortAlgo.OUTER i = 1 - 外循环。
276 [main] DEBUG SortAlgo.SWAP i = 1 j = 0 - 交换intArray [0] = 1和intArray [1] = 0
290 [main] DEBUG SortAlgo.OUTER i = 0 - 外循环。
304 [main] INFO SortAlgo.DUMP - 整数数组的转储:
317 [main] INFO SortAlgo.DUMP - 元素[0] = 0
331 [main] INFO SortAlgo.DUMP - 元素[1] = 1
343 [main] INFO examples.Sort - 下一个日志语句应该是错误消息。
346 [main] ERROR SortAlgo.DUMP - 尝试转储未初始化的数组。
在org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
在org.log4j.examples.Sort.main(Sort.java:64)
467 [main] INFO examples.Sort - 退出主要方法。
第一个字段是自程序启动以来经过的毫秒数。第二个字段是输出日志语句的线程。第三个字段是日志语句的级别。第四个字段是记录器发出日志请求的最右边的两个组件。第五个字段(在' - '之前)是嵌套诊断上下文(NDC)。请注意,嵌套诊断上下文可能为空,如前两个语句中所示。' - '后面的文本是语句的消息。
什么是记录器?
Lggers 是 log4j 的核心。记录器定义层次结构,并为程序员提供运行时控制,以控制或不打印哪些语句。记录器被分配级别。根据其级别和记录器打印日志语句。
如何在静态块中获取类的完全限定名称?
package a.b.c;
import org.apache.log4j.Logger;
public class Foo {
final static Logger logger = Logger.getLogger(Foo.class);
... other code
}
Log4j的三个主要组件
loggers
,appenders
和layouts
。这三种类型的组件协同工作,使开发人员能够根据消息类型和级别记录消息,并在运行时控制这些消息的格式以及报告的位置。
Configuration
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
public class MyApp {
// 定义静态记录器变量,使其引用
// 名为“MyApp”的记录器实例。
static Logger logger = Logger.getLogger(MyApp.class);
public static void main(String [] args) {
// 设置在控制台上登录的简单配置。
BasicConfigurator.configure();
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt()
logger.info("Exiting application.");
}
}
MyApp 首先导入 log4j 相关类。然后,它定义一个名为 MyApp 的静态记录器变量,该变量恰好是该类的完全限定名称。MyApp 使用com.foo
包中定义的 Bar 类。
package com.foo;
import org.apache.log4j.Logger;
public class Bar {
static Logger logger = Logger.getLogger(Bar.class);
public void doIt() {
logger.debug("Do it again.");
}
}
BasicConfigurator.configure
方法的调用创建了一个相当简单的 log4j 设置。此方法是硬连线的,以便将根记录器添加到 ConsoleAppender 中。输出将使用 PatternLayout 格式设置为%-4r [%t]%-5p%c%x - %m%n
模式。
请注意,默认情况下,根记录器分配给Level.DEBUG
。
MyApp 的输出是:
0 [main] INFO MyApp - Entering application.
36 [main] DEBUG com.foo.Bar - Do it again.
51 [main] INFO MyApp - Exiting application.
在 MyApp 的类通过调用配置 log4j 的BasicConfigurator.configure
方法。其他类只需要导入org.apache.log4j.Logger
类,检索他们希望使用的记录器,然后注销。前面的示例始终输出相同的日志信息。幸运的是,很容易修改 MyApp,以便在运行时控制日志输出。这是一个稍微修改过的版本。
import com.foo.Bar;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class.getName());
public static void main(String[] args) {
// 将 BasicConfigurator 替换为 PropertyConfigurator。
PropertyConfigurator.configure(args[0]);
logger.info("Entering application.");
Bar bar = new Bar();
bar.doIt();
logger.info("Exiting application.");
}
}
此版本的 MyApp 指示 PropertyConfigurator 解析配置文件并相应地设置日志记录。下面是一个示例配置文件,其结果与先前基于 BasicConfigurator 的示例相同。
# 将root logger level设置为DEBUG,将其唯一的appender设置为A1。
log4j.rootLogger=DEBUG, A1
# A1设置为ConsoleAppender。
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 使用 PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
假设我们不再对查看属于 com.foo 包的任何组件的输出感兴趣。以下配置文件显示了实现此目的的一种可能方法。
log4j.rootLogger = DEBUG,A1
log4j.appender.A1 = org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout = org.apache.log4j.PatternLayout
#以ISO 8601格式打印日期
log4j.appender.A1.layout.ConversionPattern = %d [%t]%-5p%c - %m%n
#在com.foo包中仅打印级别为WARN或更高级别的消息。
log4j.logger.com.foo = WARN