一、介绍日志发展历程
- jdk1.3 System.out.println("")追踪
只能用于写代码时调试,上线部署后,定位问题,很难找到出问题的地方。System.out.println("")只会在控制台打印日志,造成日志积压后,查询不到历史日志。 - logUtil
相对于System.out.println("")进行改进,将日志写入到文件中,方便进行定位。但仍然有很多不足需要改进 - log4j
对logUtil进行了改进
1.为了适应不同环境的需要,减少不必要的日志输出,增加了日志级别的划分。(追踪1 信息2 调试3 异常4)
2.日志文件如果过大,是否可以进行分文件存储,有些不重要的日志是否可以设置保存时间
3.记录日志文件需要进行IO交互,是否可以进行异步存储。
… - 其他日志框架
随着log4j日志框架的火热,其他日志框架横空出世。比如jul(JDK提供),log4j simple,log4j nop等等 - 日志门面
由于日志框架种类多,导致项目之间使用起来也是五花八门,这时日志门面应运而生。
日志门面:不实现日志功能,只是整合日志。
首先是:JDK开发的JCL。后来其他开发者开发的slf4j
slf4j相对性能更好 - log4j日志框架的优化
log4j功能全面,市场占有率高,但是还有个缺点就是性能不好。
apatch:对log4j进行性能优化,开发出log4j2
log4j的开发者:对log4j进行性能优化,开发出logback
总结:log4j因为性能问题,现在已经停止更新。可以直接使用log4j2和logback。而门面可以直接选择slf4j。slf4j和logback为同一个作者开发,所以日志框架建议选择logback
二、日志实例
1.直接使用日志框架
a.Jul日志框架使用
由于JDK官方开发,已归档到JDK标准库内,则无需引入依赖
public class JulController {
public static void main(String[] args) {
Logger logger = Logger.getLogger(JulController.class.getName());
logger.info("JDK官方日志框架");
}
}
b.Log4j日志框架使用
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
/**
* 开源日志框架Log4j
*/
public class Log4jController {
public static void main(String[] args) {
Logger logger = Logger.getLogger(Log4jController.class);
logger.info("开源日志框架Log4j");
}
}
还需要添加配置文件log4j.properties:指定日志打印级别、存放地方、日志格式等
#trace<debug<info<warn<error<fatal
log4j.rootLogger=trace, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] ====== %m%n
2.使用日志门面
a.JCL门面使用
<!-- 引入JCL门面依赖 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.logging.Logger;
/**
* JDK官方日志框架
*
*/
public class JulController {
public static void main(String[] args) {
/*Logger logger = Logger.getLogger(JulController.class.getName());
logger.info("JDK官方日志框架");*/
Log log = LogFactory.getLog(JulController.class);
log.info(log.getClass()+"JDK官方日志框架");
}
}
按如上进行后,观察打印的控制台,会发现使用的可能并不是Jul日志框架
原因: JCL动态查找机制进行日志实例化,执行顺序为:commons-logging.properties>系统环境变量>log4j>jul >simplelog>nooplog
解决方法:添加commons-logging.properties配置文件,指定桥接哪种日志框架
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger
b.slf4j门面使用
添加slf4j的依赖,以及针对log4j的适配器
<!-- slf4j核心依赖 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<!-- slf4j针对log4j的适配器 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 开源日志框架Log4j
*/
public class Log4jController {
public static void main(String[] args) {
/*Logger logger = Logger.getLogger(Log4jController.class);
logger.info("开源日志框架Log4j");*/
Logger logger = LoggerFactory.getLogger(Log4jController.class);
logger.info(logger.getClass()+"开源日志框架Log4j");
}
}
3.日志门面间的转换
为了日志统一实现,将JCL门面转化到SLF4J
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.30</version>
</dependency>
再运行上面的JulController的main方法,会发现使用的是Log4j的日志框架
三、springboot中日志的实现
SpringBoot底层也是使用slf4j+logback的方式进行日志记录
添加springboot依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
springboot日志文档链接:https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.logging
1.修改日志级别
修改配置文件
logging:
level:
#指定这个包下的日志级别为:跟踪,其他包下则为默认
com.tedu.logging: "trace"