Log4j1.x已经被广泛应用到各个系统及框架中。然后,1.x毕竟太古老,代码很久没有更新。目前,Log4j 1.x的代码已经很难维护,因为它依赖于很多Jdk老版本的api。作为 Log4j 1.x的替代品,SLF4J/Logback已经对日志系统做了很大的改进,那么,为什么我们还需要Log4j 2?
1. Log4j 2被设计成对安全审计有用的日志框架。在Logback框架中,当输出日志产生异常时,从来不会告诉被调用方,而log4j 2,这个将是可配置的。
2. Log4j 2使用了新一代的基于LMAX Disruptor的无锁异步日志系统。在多线程的程序中,异步日志系统吞吐量比Log4j 1.x和logback高10倍,而时间延迟却更低。
3. Log4j 2使用插件机制,更灵活。扩展appenders,Filters,Layouts,Lookups和Pattern Converters将变得更加简单,而不用去更高任何Log4j本身。
4. Log4j 2支持custom log levels。可以再程序或者配置文件中配置custom日志级别。
5. Log4j 1.x与logback返回的是String。这回产生编码的问题。Log4j 2则返回的使byte array。
6. Log4j 2的 Syslog Appender是一种SocketAppender,它不仅支持TCP和UDP还支持BSD syslog 和RFC 5424 格式。
7. Log4j1.x的一些死锁问题在logback中已经被修复,然而,logback在并发的性能上还是比较低。log4j 2利用java5的并发机制,并且性能非常好。
Log4j 2 支持三种类型的配置文件:JSON , YAML and XML。Log4j 2的配置文件加载顺序分别是:
- log4j2-test.yaml or log4j2-test.yml
- log4j2-test.json or log4j2-test.jsn
- log4j2-test.xml
- log4j2.yaml or log4j2.yml
- log4j2.json or log4j2.jsn
- log4j2.xml
如果没有找到配置文件则会用其默认的配置文件,长这样:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
也就是说,其只会把error级别的日志打印到控制台。
maven配置:
<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.3</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.3</version> </dependency>
测试类Bar.java
package com.lf.testLog4j; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; /** * Created by lufei3 on 2015/7/10. */ public class Bar { static final Logger logger = LogManager.getLogger(Bar.class.getName()); public boolean doIt() { logger.entry(); logger.error("Did it again!"); return logger.exit(false); } }
测试类HelloLog4j
package com.lf.testLog4j; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /** * Created by lufei3 on 2015/7/5. */ public class HelloLog4j { private static final Logger logger = LogManager.getLogger(HelloLog4j.class); /** * @param args */ public static void main(String[] args) { logger.trace("Entering application."); Bar bar = new Bar(); if (!bar.doIt()) { logger.error("Didn‘t do it."); } logger.trace("Exiting application."); } }
采用默认配置的输出应当是这样
ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. 14:38:42.866 [main] ERROR com.lf.testLog4j.Bar - Did it again! 14:38:42.867 [main] ERROR com.lf.testLog4j.HelloLog4j - Didn‘t do it.
增加配置文件log4j2.xml,并且把日志级别改成trace那么输出应该是这样的
15:04:42.134 [main] TRACE com.lf.testLog4j.HelloLog4j - Entering application. 15:04:42.139 [main] TRACE com.lf.testLog4j.Bar - entry 15:04:42.139 [main] ERROR com.lf.testLog4j.Bar - Did it again! 15:04:42.139 [main] TRACE com.lf.testLog4j.Bar - exit with(false) 15:04:42.139 [main] ERROR com.lf.testLog4j.HelloLog4j - Didn‘t do it. 15:04:42.139 [main] TRACE com.lf.testLog4j.HelloLog4j - Exiting application.
可以通过配置控制不同的java类的输出方式。比如我想设置Bar的输出级别为trace,而其他类的输出级别为error,配置如下:
<Loggers> <Logger name="com.lf.testLog4j.Bar" level="trace" additivity="false"> <AppenderRef ref="Console"/> </Logger> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers>
输出如下:
15:32:51.510 [main] TRACE com.lf.testLog4j.Bar - entry 15:32:51.512 [main] ERROR com.lf.testLog4j.Bar - Did it again! 15:32:51.512 [main] TRACE com.lf.testLog4j.Bar - exit with(false) 15:32:51.512 [main] ERROR com.lf.testLog4j.HelloLog4j - Didn‘t do it.
参考文献:log4j官方文档