日志框架分析及logback配置探究

来源:互联网 发布:org.apache.catalina 编辑:程序博客网 时间:2024/05/05 12:44

日志框架分析及logback配置探究


前言

虽然已经做过了好几个项目,但是在涉及框架层面的东西有很多还不是很清楚,其中就包括使用极为频繁的日志配置,很多时候会出现在控制台发现一个请求日志被请求了很多遍、日志结构混乱、日志内容繁杂等问题。在此背景下,便萌生了重整日志的想法。

正序

日志组件

JAVA有四种常见的日志组件,分别是common-logging、slf4j、log4j、logback,其中common-logging和slf4j是可以看做是桥接层或适配层,而log4j和logback则是具体的实现。适配层可以选择随意选择何种日志作为具体实现,也可在项目进行中方便的进行切换。
日志框架图

common-logging是由Apache提供的通知日志接口,用户可以自由的选择第三方日志组件作为具体实现,比如log4j、jdk自带的logging,common-logging通过动态查找机制,在程序运行时动态的查找出真正的日志库。

slf4j全称为simple logging facade for JAVA(JAVA简单日志门面),类似于common-logging,为不同日志框架提供一个门面封装。不同的是,slf4j是静态绑定原理,在编译时期即绑定到真正的log库,所以在使用slf4j时,如果要实现某种xx日志框架,必须引入正确对的桥接包slf4j-xx.jar。另外,SLF4J支持参数化的log字符串,避免了之前为了减少字符串拼接的性能损耗而不得不写的if(logger.isDebugEnable()),现在你可以直接写:logger.debug(“current user is: {}”,user)。拼装消息被推迟到了它能够确定是不是要显示这条消息的时候,但是获取参数的代价并没有幸免。

log4j是Apache的一个开源代码项目。

logback是由log4j创始人设计的又一开源日志框架,分为logback-core、logback-classic、logback-access,其中logback-core是其他两个模块的基础。

slf4j和common-logging的主要区别在于一个是静态绑定,一个是动态加载。而logback与log4j相比较,其性能要优越许多。

Spring-boot中的日志框架选择

默认情况下,spring-boot使用slf4j+logback作为日志框架,但是也可通过配置进行改变。在spring中使用logback,只需指定logback的配置文件即可。

logging.config=classpath:log/logback.xml

logback文件配置

关于logback文件配置,首先令人疑问的就是class内容的填写,在查看了logback源码之后,会发现class内容即为所使用的appender的全限定名。所以在需要时,直接打开源码,并不需要死记。
appender
如图对应的ConsoleAppender类的权限定名:
appender_name

三大标签:appender、logger、root。
1. appender表示日志打印的目的地,控制台或者文件。对于appender,有两个重要的属性标签,encoder和及其子标签pattern,在pattern中定义打印日志的编排格式。如下是一种常见的编排格式:

%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n

appender最常用的两种是ConsoleAppender和RollingFileAppender,分别表示控制台和滚动文件日志。其中Console比较简单,打印到控制台,只需定义其编排格式即可。而RollingFileAppender相比复杂一些,RollingFileAppender定义讲日志打印至文件,有三种常见滚动策略,FixedWindowRollingPolicy(固定窗口大小)、TimeBasedRollingPolicy(基于时间滚动)、TimeBasedFileNamingAndTriggeringPolicy(基于时间与文件大小)。在编写appender时,进入相应的源码即可查看到所能配置的属性及标签了。个人比较喜欢的是基于时间滚动策略,配置简单,日志根据日期清晰明了。

  1. logger用以设置某一个包或者某个类的日志打印级别,只有和logger设置级别一样或更高的日志才会被打印。每一个logger都可以设置多个appender,将日志打印到多个目的地。在logger中有一个重要属性additivity,设置是否将日志传播到祖先,注意root是所以的logger的根祖先。所以当additivity没有被适当的设置时,会出现一条日志出现了多次的混乱情况。

  2. root是所以logger的根祖先,默认情况下所有日志,包括框架级别的日志,都会传播至root。

下图是一个日志配置的完整样例:
appender_name

后记

  1. root的日志由哪来?
  2. 由logger捕获的日志,再向上传播,为何在root中能打印出比设置的level级别低的日志?
  3. 整个日志中,程序中logger语句、配置文件中的logger、配置文件的appender,整个的流程是怎样的机制?
0 0