共计 7167 个字符,预计需要花费 18 分钟才能阅读完成。
一、简介
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/log…
log4j2:https://github.com/apache/log…
本文分别来看 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,示例如下:
logging.level.root=info
logging.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 示例文件:
<?xml version=”1.0″ encoding=”UTF-8″?>
<configuration>
<!– 日志根目录 –>
<springProperty scope=”context” name=”LOG_HOME” source=”logging.path” defaultValue=”/data/logs/spring-boot-logback”/>
<!– 日志级别 –>
<springProperty scope=”context” name=”LOG_ROOT_LEVEL” source=”logging.level.root” defaultValue=”DEBUG”/>
<!– 标识这个 ”STDOUT” 将会添加到这个 logger –>
<springProperty scope=”context” name=”STDOUT” source=”log.stdout” defaultValue=”STDOUT”/>
<!– 日志文件名称 –>
<property name=”LOG_PREFIX” value=”spring-boot-logback” />
<!– 日志文件编码 –>
<property name=”LOG_CHARSET” value=”UTF-8″ />
<!– 日志文件路径 + 日期 –>
<property name=”LOG_DIR” value=”${LOG_HOME}/%d{yyyyMMdd}” />
<!– 对日志进行格式化 –>
<property name=”LOG_MSG” value=”- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | –> %msg|%n “/>
<!– 文件大小,默认 10MB–>
<property name=”MAX_FILE_SIZE” value=”50MB” />
<!– 配置日志的滚动时间,表示只保留最近 10 天的日志 –>
<property name=”MAX_HISTORY” value=”10″/>
<!– 输出到控制台 –>
<appender name=”STDOUT” class=”ch.qos.logback.core.ConsoleAppender”>
<!– 输出的日志内容格式化 –>
<layout class=”ch.qos.logback.classic.PatternLayout”>
<pattern>${LOG_MSG}</pattern>
</layout>
</appender>
<!– 输出到文件 –>
<appender name=”0″ class=”ch.qos.logback.core.rolling.RollingFileAppender”>
</appender>
<!– 定义 ALL 日志的输出方式:–>
<appender name=”FILE_ALL” class=”ch.qos.logback.core.rolling.RollingFileAppender”>
<!– 日志文件路径,日志文件名称 –>
<File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>
<!– 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件,默认 10MB –>
<rollingPolicy class=”ch.qos.logback.core.rolling.TimeBasedRollingPolicy”>
<!– 日志文件路径,新的 ALL 日志文件名称,“i”是个变量 –>
<FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>
<!– 配置日志的滚动时间,表示只保留最近 10 天的日志 –>
<MaxHistory>${MAX_HISTORY}</MaxHistory>
<!– 当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件,默认 10MB–>
<timeBasedFileNamingAndTriggeringPolicy class=”ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP”>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!– 输出的日志内容格式化 –>
<layout class=”ch.qos.logback.classic.PatternLayout”>
<pattern>${LOG_MSG}</pattern>
</layout>
</appender>
<!– 定义 ERROR 日志的输出方式:–>
<appender name=”FILE_ERROR” class=”ch.qos.logback.core.rolling.RollingFileAppender”>
<!– 下面为配置只输出 error 级别的日志 –>
<filter class=”ch.qos.logback.classic.filter.LevelFilter”>
<level>ERROR</level>
<OnMismatch>DENY</OnMismatch>
<OnMatch>ACCEPT</OnMatch>
</filter>
<!– 日志文件路径,日志文件名称 –>
<File>${LOG_HOME}/err_${LOG_PREFIX}.log</File>
<!– 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件,默认 10MB –>
<rollingPolicy class=”ch.qos.logback.core.rolling.TimeBasedRollingPolicy”>
<!– 日志文件路径,新的 ERR 日志文件名称,“i”是个变量 –>
<FileNamePattern>${LOG_DIR}/err_${LOG_PREFIX}%i.log</FileNamePattern>
<!– 配置日志的滚动时间,表示只保留最近 10 天的日志 –>
<MaxHistory>${MAX_HISTORY}</MaxHistory>
<!– 当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件,默认 10MB–>
<timeBasedFileNamingAndTriggeringPolicy class=”ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP”>
<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<!– 输出的日志内容格式化 –>
<layout class=”ch.qos.logback.classic.PatternLayout”>
<Pattern>${LOG_MSG}</Pattern>
</layout>
</appender>
<!– additivity 设为 false, 则 logger 内容不附加至 root,配置以配置包下的所有类的日志的打印,级别是 ERROR–>
<logger name=”org.springframework” level=”ERROR” />
<logger name=”org.apache.commons” level=”ERROR” />
<logger name=”org.apache.zookeeper” level=”ERROR” />
<logger name=”com.alibaba.dubbo.monitor” level=”ERROR”/>
<logger name=”com.alibaba.dubbo.remoting” level=”ERROR” />
<!– ${LOG_ROOT_LEVEL} 日志级别 –>
<root level=”${LOG_ROOT_LEVEL}”>
<!– 标识这个 ”${STDOUT}” 将会添加到这个 logger –>
<appender-ref ref=”${STDOUT}”/>
<!– FILE_ALL 日志输出添加到 logger –>
<appender-ref ref=”FILE_ALL”/>
<!– FILE_ERROR 日志输出添加到 logger –>
<appender-ref ref=”FILE_ERROR”/>
</root>
</configuration>
2.4 代码中使用日志
在代码中使用日志,只需要使用如下代码:
private Logger logger = LoggerFactory.getLogger(this.getClass());
//…
logger.debug(“this is debug”);
logger.info(“this is info”);
三、Log4j2 集成
3.1 配置依赖组件
Spring Boot 添加 Log4j2 依赖的同时,需要排除 Logback 依赖,配置 pom.xml 代码如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions><!– 去掉 logback 配置 –>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency> <!– 引入 log4j2 依赖 –>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
3.2 自定义日志配置
添加 log4j2-spring.xml 文件在 src/main/resources 文件下,配置文件代码如下:
<?xml version=”1.0″ encoding=”UTF-8″?>
<configuration>
<Appenders>
<Console name=”CONSOLE” target=”SYSTEM_OUT”>
<PatternLayout charset=”UTF-8″ pattern=”[%-5p] %d %c – %m%n” />
</Console>
<File name=”File” fileName=”D:\\mylog.log”>
<PatternLayout pattern=”%m%n” />
</File>
</Appenders>
<Loggers>
<root level=”info”>
<AppenderRef ref=”CONSOLE” />
<AppenderRef ref=”File” />
</root>
</Loggers>
</configuration>
输入日志到控制台和 D 盘 mylog.log 文件中。
到此为止,已经完成了 log4j2 的集成,运行项目,查看日志。
示例源码:https://github.com/vipstone/s…
参考资料
JAVA 日志的前世今生:https://www.cnblogs.com/xiexj…