因为公司业务需要,目前的log4j 1.x 遇到死锁,需要升级到Log4j 2.x。现在对目前的日志框架进行调研,并根据目前的现状提出升级的方法。
一引言
对于一个应用程序来说日志记录是必不可少的一部分。线上问题追踪,基于日志的业务逻辑统计分析等都离不日志。Java领域存在多种框架,目前比较常用的日志框架包括:Log4j、Log4J2、Commons Logging、Slf4j、Logback和Jul。Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。Log4j 2是apache开发的一款Log4j的升级产品。Commons Logging Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging。Slf4j 类似于Commons Logging,是一套简易Java日志门面,本身并无日志的实现。(Simple Logging Facade for Java,缩写Slf4j)。Logback 一套日志组件的实现(slf4j阵营)。Jul (Java Util Logging),自Java1.4以来的官方日志实现。
由于目前公司使用的日志系统是以Log4j 1.x 为主,Log4J 1.x由于已经停止更新和维护,其中存在的消息丢失和阻塞问题严重,所以对现有点的业务造成的很大的影响。同时由于各个系统使用的日志框架混乱,在系统中同时使用Log4j1.x、JDK自带的Logging和Logback。所以需要统一升级一下框架。
目前业界主要使用的是Log4j1.x、Log4j 2.x和logback。由于Log4j 2 是 Log4j 的升级版本,该版本比起前任来说有着显著的改进,包含很多在 Logback 中的改进以及Logback 架构中存在的问题。所以本文会根据日志的发展路线着重调研Log4j1.x中存在的问题,以及logback和Log4j2.x的优点。最后给出日志系统版本升级的建议。
二调研对象
1 log4j 1.x
Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。
Log4j主要有三个组件:Loggers(记录器),Appenders (输出源)和Layouts(布局),这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松的记录信息的类型和级别,并可以在运行时控制日志输出的样式和位置。一个典型的Log4j的配置文件log4j.properties如下图1-1所示:
图1-1
其中info代表的是记录器的级别,console代表的是记录器的名称,下面四行是对记录器console的配置。
在使用Log4j 1.x过程中出现了一些问题,如死锁、内存溢出和效率不高等现象。
2 logback 相对于Log4j 1.x的改进
Logback是由log4j创始人Ceki 设计的又一个开源日志组件,用来取代log4j的一个日志框架,是slf4j的原生实现。logback当前分成三个模块:logback-core、logback- classic和logback-access。
logback-core是其它两个模块的基础模块,而logback-classic是log4j的一个改良版本,同时它完整实现了slf4j API,使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging等。logback-access提供了访问模块与Servlet容器集成提供通过Http来访问日志的功能。
2.1更快的执行速度
在Log4j 1.x 的基础上,logback 重写了内部的实现,在某些特定的场景上面,甚至可以比之前的速度快上10倍。比如Logback内部的消息队列采用了ArrayBlockingQueue,相对于原始的ArrayList和锁操作来说,管程类的消息队列拥有更好地性能。同时在保证logback的组件更加快速的同时,同时所需的内存更加少。
2.2实现SLF4J
logback-classic中的类自然的实现了SLF4J。使用 logback-classic作为底层实现时,涉及到LF4J日记系统的问题你完全不需要考虑。更进一步来说,由于 logback-classic强烈建议使用SLF4J作为客户端日记系统实现,如果需要切换到log4j或者