一、简介
Java知名的日志有很多,比如:JUL、Log4j、JCL、SLF4J、Logback、Log4j2,那么这些日志框架之间有着怎样的关系?诞生的原因又是解决什么问题?下面一起来看。
<!--more-->1.1 JUL
Java有自己的日志框架JUL(Java Util Logging)在java.util.logging下,因为对开发者不友好,使用成本太高和日志级别分类不清晰的问题,所有很少有开发者用。
1.2 Log4j
因为JUL的缺陷问题,这就给了Log4j机会,所有Log4j一经推出就迅速风靡全球。
1.3 JCL
JCL是Jakarta Commons-Logging的缩写,Jakarta在这里指的是一个组织,而不是印度的首都雅加达,Jakarta,一个早期的Apache开源项目,用于管理各个Java子项目,诸如Tomcat, Ant, Maven, Struts, JMeter, Velocity, JMeter, Commons等。2011年12月,在所有子项目都被迁移为独立项目后,Jakarta名称就不再使用了。
JCL诞生的初衷是因为Java自身的一些包用了JUL,而Log4j用户使用的有很多,那么JCL就是提供一套API来实现不同Logger之间的切换。
1.4 SLF4J
SLF4J(Simple Logging Facade For Java)简单日志门面,和JCL功能类似,但JCL有一个致命的缺点就是算法复杂,出现问题难以排除,而SLF4J的诞生就是为了解决JCL的缺点。
值得一提的是SLF4J的作者就是Log4j的作者。
1.5 Logback
Logback是Log4j的作者的另一个开源日志组件,与Log4j相比,Logback重新了内核,使它的性能提升了很多,大约是Log4j的10倍,同时占用更小的内存,并且完整的实现了SLF4J API是你可以很方便的切换日志框架。
1.6 Log4j2
Log4j2有着和Logback相同的功能,但又有自己单用的功能,比如:插件式结构、配置文件优化、异步日志等。
Log4j2是Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些固有问题。
从GitHub的更新日志来看,Logback已经有半年没有更新了,而作为知名组织的Apache下的Log4j2的更新却是非常活跃的,Log4j 1.x 于2015年8月停止维护更新了。
GitHub地址
Logback:https://github.com/qos-ch/logback
log4j2:https://github.com/apache/logging-log4j2
本文分别来看Logback和Log4j2在Spring Boot中的实现。
二、Logback使用
开发环境
- JDK 8
- Spring Boot 2.0.4 RELEASE
- Maven
- Windows 10
- IDEA 2018.2
2.1 Logback的使用
Spring Boot默认集成了Logback,可以开箱即用,非常方便。因为spring-boot-starter-logging是Logback的日志实现,而Spring Boot启动项spring-boot-starter又依赖了spring-boot-starter-logging,所以Spring Boot就默认集成了Logback,包依赖如下图:

日志是默认控制台输出的,我们程序启动的时候就使用Logback,如下图所示:

日志组成解读:
-
日期和时间:毫秒精度,易于排序
-
日志级别:trace、debug、info、warn、error(日志级别依次从低到高)
-
进程ID
-
---分隔符 -
线程名称:括在方括号中(可以截断控制台输出)
-
记录器名称:这通常是源类名(通常缩写)
-
日志具体信息
2.2 输入文件
如果需要输出日志到文件,只需要在application.properties配置文件设置:logging.file或logging.path,示例如下:
1logging.level.root=info 2logging.file=D:\\log\\my.log
可以通过设置日志的级别,忽略更低级别的日志输出。
注意: logging.file和logging.path设置一个属性即可,如果两个都设置,则以logging.file为主,logging.path无效。
日志文件容量设置:使用“logging.file.max-history”属性为日志最大容量设置,默认10M超过则分割为多个文件。
2.3 自定义日志配置
日志服务在ApplicationContext创建前就初始化了,所以通过设置属性和传统的配置XML文件,可以对日志进行管理和控制。
只需要在src/main/resources下,创建好约定名称的XML文件,即可完成对日志系统的设置,不同的日志系统有不同的约定名称,如下列表:
日志
名称
logback
logback-spring.xml, logback-spring.groovy, logback.xml, 或者 logback.groovy
log4j2
log4j2-spring.xml 或者 log4j2.xml
Spring Boot官方建议使用“-spring”的命名规则,进行日志配置,如:logback-spring.xml而不是logback.xml。
当然你也可以自定义日志名称,只需要在application.properties配置即可,代码如下:
logging.config=classpath:logging-config.xml
来看一个logback-spring.xml示例文件:
1<?xml version="1.0" encoding="UTF-8"?> 2<configuration> 3 4 <!-- 日志根目录--> 5 <springProperty scope="context" name="LOG_HOME" source="logging.path" defaultValue="/data/logs/spring-boot-logback"/> 6 7 <!-- 日志级别 --> 8 <springProperty scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="DEBUG"/> 9 10 <!-- 标识这个"STDOUT" 将会添加到这个logger --> 11 <springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/> 12 13 <!-- 日志文件名称--> 14 <property name="LOG_PREFIX" value="spring-boot-logback" /> 15 16 <!-- 日志文件编码--> 17 <property name="LOG_CHARSET" value="UTF-8" /> 18 19 <!-- 日志文件路径+日期--> 20 <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" /> 21 22 <!--对日志进行格式化--> 23 <property name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/> 24 25 <!--文件大小,默认10MB--> 26 <property name="MAX_FILE_SIZE" value="50MB" /> 27 28 <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志--> 29 <property name="MAX_HISTORY" value="10"/> 30 31 <!--输出到控制台--> 32 <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 33 <!-- 输出的日志内容格式化--> 34 <layout class="ch.qos.logback.classic.PatternLayout"> 35 <pattern>${LOG_MSG}</pattern> 36 </layout> 37 </appender> 38 39 <!--输出到文件--> 40 <appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender"> 41 </appender> 42 43 <!-- 定义 ALL 日志的输出方式:--> 44 <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender"> 45 <!--日志文件路径,日志文件名称--> 46 <File>${LOG_HOME}/all_${LOG_PREFIX}.log</File> 47 48 <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB --> 49 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 50 51 <!--日志文件路径,新的 ALL 日志文件名称,“ i ” 是个变量 --> 52 <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern> 53 54 <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志--> 55 <MaxHistory>${MAX_HISTORY}</MaxHistory> 56 57 <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB--> 58 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 59 <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> 60 </timeBasedFileNamingAndTriggeringPolicy> 61 62 </rollingPolicy> 63 64 <!-- 输出的日志内容格式化--> 65 <layout class="ch.qos.logback.classic.PatternLayout"> 66 <pattern>${LOG_MSG}</pattern> 67 </layout> 68 </appender> 69 70 <!-- 定义 ERROR 日志的输出方式:--> 71 <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> 72 <!-- 下面为配置只输出error级别的日志 --> 73 <filter class="ch.qos.logback.classic.filter.LevelFilter"> 74 <level>ERROR</level> 75 <OnMismatch>DENY</OnMismatch> 76 <OnMatch>ACCEPT</OnMatch> 77 </filter> 78 <!--日志文件路径,日志文件名称--> 79 <File>${LOG_HOME}/err_${LOG_PREFIX}.log</File> 80 81 <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB --> 82 <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> 83 84 <!--日志文件路径,新的 ERR 日志文件名称,“ i ” 是个变量 --> 85 <FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}%i.log</FileNamePattern> 86 87 <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志--> 88 <MaxHistory>${MAX_HISTORY}</MaxHistory> 89 90 <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB--> 91 <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 92 <maxFileSize>${MAX_FILE_SIZE}</maxFileSize> 93 </timeBasedFileNamingAndTriggeringPolicy> 94 </rollingPolicy> 95 96 <!-- 输出的日志内容格式化--> 97 <layout class="ch.qos.logback.classic.PatternLayout"> 98 <Pattern>${LOG_MSG}</Pattern> 99 </layout> 100 </appender> 101 102 <!-- additivity 设为false,则logger内容不附加至root ,配置以配置包下的所有类的日志的打印,级别是 ERROR--> 103 104 <logger name="org.springframework" level="ERROR" /> 105 <logger name="org.apache.commons" level="ERROR" /> 106 <logger name="org.apache.zookeeper" level="ERROR" /> 107 <logger name="com.alibaba.dubbo.monitor" level="ERROR"/> 108 <logger name="com.alibaba.dubbo.remoting" level="ERROR" /> 109 110 <!-- ${LOG_ROOT_LEVEL} 日志级别 --> 111 <root level="${LOG_ROOT_LEVEL}"> 112 113 <!-- 标识这个"${STDOUT}"将会添加到这个logger --> 114 <appender-ref ref="${STDOUT}"/> 115 116 <!-- FILE_ALL 日志输出添加到 logger --> 117 <appender-ref ref="FILE_ALL"/> 118 119 <!-- FILE_ERROR 日志输出添加到 logger --> 120 <appender-ref ref="FILE_ERROR"/> 121 </root> 122 123</configuration>
2.4 代码中使用日志
在代码中使用日志,只需要使用如下代码:
1private Logger logger = LoggerFactory.getLogger(this.getClass()); 2//... 3logger.debug("this is debug"); 4logger.info("this is info");
三、Log4j2集成
3.1 配置依赖组件
Spring Boot添加Log4j2依赖的同时,需要排除Logback依赖,配置pom.xml代码如下:
1<dependencies> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-web</artifactId> 5 <exclusions><!-- 去掉logback配置 --> 6 <exclusion> 7 <groupId>org.springframework.boot</groupId> 8 <artifactId>spring-boot-starter-logging</artifactId> 9 </exclusion> 10 </exclusions> 11 </dependency> 12 13 <dependency> <!-- 引入log4j2依赖 --> 14 <groupId>org.springframework.boot</groupId> 15 <artifactId>spring-boot-starter-log4j2</artifactId> 16 </dependency> 17</dependencies>
3.2 自定义日志配置
添加log4j2-spring.xml文件在src/main/resources文件下,配置文件代码如下:
1<?xml version="1.0" encoding="UTF-8"?> 2<configuration> 3 <Appenders> 4 <Console name="CONSOLE" target="SYSTEM_OUT"> 5 <PatternLayout charset="UTF-8" pattern="[%-5p] %d %c - %m%n" /> 6 </Console> 7 8 <File name="File" fileName="D:\\mylog.log"> 9 <PatternLayout pattern="%m%n" /> 10 </File> 11 </Appenders> 12 13 <Loggers> 14 <root level="info"> 15 <AppenderRef ref="CONSOLE" /> 16 <AppenderRef ref="File" /> 17 </root> 18 </Loggers> 19</configuration>
输入日志到控制台和D盘mylog.log文件中。
到此为止,已经完成了log4j2的集成,运行项目,查看日志。
示例源码:https://github.com/vipstone/springboot-example/tree/master/springboot-logging
参考资料
JAVA日志的前世今生:https://www.cnblogs.com/xiexj/p/9417128.html