前言
几乎每个大型应用程序都包含自己的日志或跟踪API。为了符合这一规则,欧盟SEMPRER项目决定编写自己的跟踪API。这是在1996年初。经过无数次的增强、几个版本和大量的工作之后,API演变成了log4j,这是一个流行的Java日志包。这个包是在Apache Software License下发布的,Apache Software License是由开源组织认证的完全成熟的开源许可证。
然而随着技术的发展,Log4j的结构、性能被很多新的日志框架所替代。它在设计结构上比不上slf4j,在性能上比不上logback。于是apache对垂垂老矣的Log4j进行一次重生,是重生,而不是优化。虽然都叫Log4j。但是,它们是两个完全不同的东西,为了方便区分他们,给了两个别名:Log4j1、Log4j2。
Log4j1与Log4j2的区别
设计理念的区别
slf4j的成功在于他的高屋建瓴,俯视一切。
slf4j是日志门面(像:java的接口,没有提供任何实现),通过提供各种桥接器,适配各种日志框架(Log4j1,logback等)。
Log4j1并没有这样的高度,于是Log4j2就借鉴了slf4j的设计。
Log4f2有两部分组成:log4j-api、log4j-core。
其中log4j-api和slf4j是相同的,都是日志门面,log4j-core则是对log4j-api的实现,和log4j1、logback是相同的, 并且通过桥接器log4j-api还可以适配其他的日志系统(logback等)。
就这样,Log4j2集成了slf4j与logback的优点,成为了Log4j的一次重生。
核心Jar包的区别
上面我们就说了,Log4j有两部分组成,分别是log4j-api、log4j-core
而在Log4j1中,Log4j的核心包只有log4j:log4j:[version]
而log4j2的核心包有2个:
org.apache.logging.log4j:log4j-core:[version]
org.apache.logging.log4j:log4j-api:[version]
引入Jar包的区别
//log4j1:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
//log4j2:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.1</version>
</dependency>
//log4j-core包中已经引入了log4j-api
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency>
log4j1、log4j2中类的包名的区别:
Log4j1中类的包名都是以 org.apache.log4j 开头
Log4j2中,log4j-api中的类包名以 org.apache.logging.log4j 开头,log4j-core中的类包名以 org.apache.logging.log4j.core 开头。
配置文件的区别
Log4j:通过一个log4j.properties的文件作为主配置文件。
以下是一个输出到控制台的例子:
log4j.rootLogger=INFO,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%p] [%thread] [%c] >>> %m%n
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:%m 输出代码中指定的消息:
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例: Testlog4.main(TestLog4.java:10)
而在Log4j2中,Log4j2已经弃用了.properties方式,采用的是.xml,.json或者.jsn这种方式来做。
log4j2.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[I am log4j_2.x] [%-d{yyyy-MM-dd HH:mm:ss}]-%5p : %m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
调用方式的区别
Log4j1中
import org.apache.log4j.Logger;
private static final Logger logger = Logger.getLogger(App.class);
而在Log4j2中
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
private static final Logger logger = LogManager.getLogger(App.class);
测试用例
public class Log4jTest {
public static void main(String[] args) {
org.apache.log4j.Logger log4j1 = org.apache.log4j.LogManager.getLogger(Log4jTest.class);
log4j1.info("log4j1日志" + log4j1.getClass().getName());
org.apache.logging.log4j.Logger log4j2 = org.apache.logging.log4j.LogManager.getLogger(Log4jTest.class);
log4j2.info("log4j2日志" + log4j2.getClass().getName());
}
}
输出结果为: