Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?

Posted VeryJava

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?相关的知识,希望对你有一定的参考价值。

 

用了这么久的日志框架,你它们完全了解吗?程序哥之前了解的,但是现在记得不清楚了,可惜之前看的时候没记录,现在就和大家一起看看。带着这个问题“阿里巴巴Java开发手册为什么推荐使用Slf4j? 而且还是强制!”

【强制】应用中不可直接使用日志系统(Log4j、 Logback) 中的 API,而应依赖使用日志框架SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);

Hi~ 各位小伙伴们! 关注+收藏,然后再看,养成习惯,我是程序哥!求职面试,微信搜索【VeryJava】,私我进群啦!

Log4j

概述

Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、数据库等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

日志级别

Log4j有8种不同的log级别,按照等级从低到高依次为:ALL、TRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFF。如果配置为OFF级别,表示关闭log。

  • All:最低等级的,用于打开所有日志记录。
  • TRACE:designates finer-grained informational events than the DEBUG.Since:1.2.12,很低的日志级别,一般不会使用。
  • DEBUG:指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
  • INFO:消息在粗粒度级别上突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志。
  • WARN:表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给程序员的一些提示。
  • ERROR:指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别。
  • FATAL:指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
  • OFF:最高等级的,用于关闭所有日志记录。

如果将log level设置在某一个级别上,那么比此级别优先级高的log都能打印出来。例如,如果设置优先级为WARN,那么OFF、FATAL、ERROR、WARN 4个级别的log能正常输出,而INFO、DEBUG、TRACE、 ALL级别的log则会被忽略。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。

文件格式

Log4j支持两种格式的配置文件:properties和xml。包含三个主要的组件:Logger、appender、Layout。

  • Logger:日志记录器,负责收集处理日志记录,可以有选择的启动和禁用日志的输出。
  • Appender:日志输出目的地,负责日志的输出,一个输出源就叫一个Appender,appender的类别有:Console(控制台)File(文件)JDBC、JMS等,logger可以通过方法logger.addAppender(appender);配置多个appender,对logger来说,每个有效的日志请求结果都将输出到logger本身以及父logger的appender上。
  • Layout:日志格式化,负责对输出的日志格式化。

一个logger可以对应多个appender,一个appender只能对应一个layout。

org.apache.log4j.htmlLayout(以HTML表格形式布局)
org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

例如通过如下配置,设定root日志的输出级别为INFO,appender为控制台输出stdout:

# LOG4J配置
log4j.rootLogger=INFO,stdout
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n

例如通过文件在线上环境持久化日志:

# LOG4J配置
log4j.rootLogger=INFO,stdout,file
# 日志输出到文件
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.file.file=logs/springboot.log 
log4j.appender.file.DatePattern='.'yyyy-MM-dd 
log4j.appender.file.layout=org.apache.log4j.PatternLayout 
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n

例如输出到数据库mysql

# LOG4J配置
log4j.rootCategory=INFO,stdout,jdbc
# 数据库输出
log4j.appender.jdbc=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.jdbc.driver=com.mysql.jdbc.Driver
log4j.appender.jdbc.URL=jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&useSSL=true
log4j.appender.jdbc.user=root
log4j.appender.jdbc.password=root
log4j.appender.jdbc.sql=insert into log_icecoldmonitor(level,category,thread,time,location,note) values('%p','%c','%t','%d{yyyy-MM-dd HH:mm:ss:SSS}','%l','%m')

# 日志的mysql表
CREATE TABLE `log_icecoldmonitor` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `level` varchar(255) NOT NULL DEFAULT '' COMMENT '优先级',
  `category` varchar(255) NOT NULL DEFAULT '' COMMENT '类目',
  `thread` varchar(255) NOT NULL DEFAULT '' COMMENT '进程',
  `time` varchar(30) NOT NULL DEFAULT '' COMMENT '时间',
  `location` varchar(255) NOT NULL DEFAULT '' COMMENT '位置',
  `note` text COMMENT '日志信息',
  PRIMARY KEY (`Id`)
)

Log4j2

Spring Boot1.4以及之后的版本已经不支持log4j,log4j也很久没有更新了,现在已经有很多其他的日志框架对Log4j进行了改良,比如说SLF4J、Logback等。而且Log4j2在各个方面都与Logback非常相似,那么为什么我们还需要Log4j2呢?


    1. 插件式结构。Log4j2支持插件式结构。我们可以根据自己的需要自行扩展Log4j2. 我们可以实现自己的appender、logger、filter。

    1. 配置文件优化。在配置文件中可以引用属性,还可以直接替代或传递到组件。而且支持json格式的配置文件。不像其他的日志框架,它在重新配置的时候不会丢失之前的日志文件。

    1. Java5的并发性。Log4j2利用Java5中的并发特性支持,尽可能地执行最低层次的加锁。解决了在log4j1.x中存留的死锁的问题。

    1. 异步logger。Log4j2是基于LMAX Disruptor库的。在多线程的场景下,和已有的日志框架相比,异步的logger拥有10倍左右的效率提升。

异步日志

官方建议一般程序员查看的日志改成异步方式,一些运营日志改成同步。日志异步输出的好处在于,使用单独的进程来执行日志打印的功能,可以提高日志执行效率,减少日志功能对正常业务的影响。异步日志在程序的classpath需要加载disruptor-3.0.0.jar或者更高的版本。

<!-- log4j2异步日志需要加载disruptor-3.0.0.jar或者更高的版本 -->
<dependency>
   <groupId>com.lmax</groupId>
   <artifactId>disruptor</artifactId>
   <version>3.3.6</version>
</dependency>

异步日志分为两种:

  • a.全异步模式 这种异步日志方式,不需要修改修改原理的配置文件,Logger仍然使用 and 只需要在主程序代码开头,加一句系统属性的代码:
  System.setProperty("Log4jContextSelector""org.apache.logging.log4j.core.async.AsyncLoggerContextSelector");  
  • b.异步和非异步混合输出模式 在配置文件中Logger使用 or
  <loggers>  
     <AsyncLogger name="AsyncLogger" level="trace" includeLocation="true">  
        <appender-ref ref="Console" />  
        <appender-ref ref="debugLog" />  
        <appender-ref ref="errorLog" />  
    </AsyncLogger>  
 
    <asyncRoot level="trace" includeLocation="true">  
        <appender-ref ref="Console" />  
    </asyncRoot>   
</loggers> 

log4j2.xml配置 有一点需要注意的是,假如想要在application.properties中指定日志文件存放路径或日志文件名,在log4j2.xml中使用{LOG_FILE}来引用,是无法获取到的(在logback中可以尽情使用)。log4j2支持xml、json、yaml等格式的配置文件。

Logback

Logback,一个“可靠、通用、快速而又灵活的Java日志框架”。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。

logback-core: Joran, Status, context, pattern parsing
logback-classic: developer logging
logback-access: The log generated when a user accesses a web-page on a web server. Integrates seamlessly with Jetty and Tomcat.

logback的理由:

logback比log4j要快大约10倍,而且消耗更少的内存。logback-classic模块直接实现了SLF4J的接口,所以我们迁移到logback几乎是零开销的。logback不仅支持xml格式的配置文件,还支持groovy格式的配置文件。相比之下,Groovy风格的配置文件更加直观,简洁。logback-classic能够检测到配置文件的更新,并且自动重新加载配置文件。logback能够优雅的从I/O异常中恢复,从而我们不用重新启动应用程序来恢复logger。logback能够根据配置文件中设置的上限值,自动删除旧的日志文件。logback能够自动压缩日志文件。logback能够在配置文件中加入条件判断(if-then-else)。可以避免不同的开发环境(dev、test、uat…)的配置文件的重复。logback带来更多的filter。logback的stack trace中会包含详细的包信息。logback-access和Jetty、Tomcat集成提供了功能强大的HTTP-access日志。配置文件:需要在项目的src目录下建立一个logback.xml。注:(1)logback首先会试着查找logback.groovy文件;(2)当没有找到时,继续试着查找logback-test.xml文件;(3)当没有找到时,继续试着查找logback.xml文件;(4)如果仍然没有找到,则使用默认配置(打印到控制台)。

SLF4J

最后再来说说SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,而是通过Facade Pattern提供一些Java logging API,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。作者创建SLF4J的目的是为了替代Jakarta Commons-Logging。

实际上,SLF4J所提供的核心API是一些接口以及一个LoggerFactory的工厂类。在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。类似于Apache Common-Logging,SLF4J是对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑定真正的Log库。使用SLF4J时,如果你需要使用某一种日志实现,那么你必须选择正确的SLF4J的jar包的集合(各种桥接包)。

SLF4J提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。

为什么使用SLF4J?

如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用JDK 1.8 Logging的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用SLF4J,那么这种转换将是非常轻松的事情。

总结

下面是SLF4J官方的一张图:Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?

Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?
  • 接口:将所有日志实现适配到了一起,用统一的接口调用。
  • 实现:目前主流的日志实现。
  • 旧日志到slf4j的适配器:如果使用了slf4j,但是只想用一种实现,想把log4j的日志体系也从logback输出,这个是很有用的。
  • slf4j到实现的适配器:如果想制定slf4j的具体实现,需要这些包。 Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?

slf4j跟commons-logging类似,是各种日志实现的通用入口,log4j、log4j2、logback、slf4j-simple和java.util.logging是比较常见的日志实现系统,目前应用比较广泛的是Log4j和logback,而logback作为后起之秀,以替代log4j为目的,整体性能比log4j较佳,log4j的升级版log4j2也是有诸多亮点,用户可以根据项目需求和个人习惯,选择合适的日志实现。

面经放送

还在找工作的同学,后台"留言+VX",程序哥亲自整理的各种面经和资料PDF,思维导图大放送啦!!!Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?


欢迎关注, 后台留言“加群”,进群查看各个公司的最新开奖消息和面试信息。

参考

  • http://www.slf4j.org/
  • http://logback.qos.ch/
  • http://logging.apache.org/log4j/2.x/
  • https://blog.csdn.net/zwj1030711290/article/details/81010320
  • https://www.jianshu.com/p/2d5bf5e20467

以上是关于Log4j,Log4j2,Logback,Slf4J日志框架你真的了解吗?阿里巴巴Java开发手册为什么强制推荐使用Slf4j?的主要内容,如果未能解决你的问题,请参考以下文章

slf4j 怎么调用 log4j

slf4j与log4j是什麽关系?

Log4j,Log4j2,logback,slf4j日志学习

slf4j-api,slf4j-log4j12以及log4j之间啥关系

log4j和slf4j的使用

Log4j,Log4j2,logback,slf4j日志学习