1.市面上的日志框架
JUL(java util logging)、logback、log4j、log4j2
JCL(Jakarta Commons Logging)、slf4j( Simple Logging Facade for Java)
日志门面
JCL、slf4j
日志实现
JUL、logback、log4j、log4j2
现在日志的门面基本统一都是使用的slf4j,而日志实现的话可以选择我log4j2或者logback,这里需要注意一下,slf4j、log4j、logback这三个是出自同一个人,而log4j2则是Apache的。
2.SpringBoot中的默认日志框架
SpringBoot中默认使用SLF4J和Logback。
3.SpringBoot中日志框架的使用
在开发的时候,日志记录方法的使用,不应该直接调用日志的实现类,而是调用日志的抽象层的方法。
案例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
需要注意的是,slf4j只是提供接口,每个不同的日志框架的具体实现类需要配置自己的配置文件。
下图是SLF4J的官网上的各种实现关系:
引入日志框架如何解决冲突:
当应用的其他jar中有其他的日志实现,就会导致冲突,就需要用中间的jar进行替换,才可以解决,下图就是slf4j官网的冲突的解决图。
如何让应用的中jar统一使用slf4j(即如上图展示):
- 将系统中其他日志框架先排除出去;
- 用中间包来替换原有的日志框架;
- 我们导入slf4j其他的实现(我们自己想用的实现)
3.1 SpringBoot中的日志关系
SpringBoot使用它来做日志功能:
当我们引入springboot的web模块时,就引入这个依赖:
org.springframework.boot
spring‐boot‐starter‐logging
底层依赖关系:
总结:
1)、SpringBoot底层也是使用slf4j+logback的方式进行日志记录
2)、SpringBoot也把其他的日志都替换成了slf4j;
3)、中间替换包的引入
中间替换包的简单案例:
@SuppressWarnings("rawtypes")
public abstract class LogFactory {
static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J =
"http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";
static LogFactory logFactory = new SLF4JLogFactory();
他在代码中做了替换,包名还是和你原来使用的包名一样,虽然你使用的还是原来的,但是真正的实现类已经被替换了。
4)、如果我们要引入其他框架?一定要把这个框架的默认日志依赖移除掉
eg:
Spring框架用的是commons-logging;
org.springframework
spring‐core
commons‐logging
commons‐logging
SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要
把这个框架依赖的日志框架排除掉即可;
3.2 SpringBoot中日志的配置与使用
1. 默认配置
SpringBoot默认帮我们配置好了日志;我们直接启动项目就可以看到控制台有日志输出。
//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
//日志的级别;
//由低到高 trace
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%‐5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
‐‐>
%d{yyyy‐MM‐dd HH:mm:ss.SSS} [%thread] %‐5level %logger{50} ‐ %msg%n
2.修改日志的默认配置
在springboot的配置文件中修改默认配置
# 指定某个包下的类的日志输出级别
logging.level.com.njit=trace
# 设置springboot默认的日志级别,springboot默认的日志级别就是root,这里指定root的具体级别
# logging.level.root=warn
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=D:/springboot.log
# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
logging.path=/spring/log
# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy‐MM‐dd} === [%thread] === %‐5level === %logger{50} ==== %msg%n
注:如果logging.path 和 logging.file同时存在,则以logging.file为准
通过自己的配置文件覆盖默认的配置
springboot中的默认配置文件在你引入的springboot的依赖下的logging目录下,有log4j2和logback的默认配置:
如果你在给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了
logback.xml:直接就被日志框架识别了;
logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
可以指定某段配置只在某个环境下生效
比如,在dev环境输出的格式和非dev环境的格式不同,可以指定不同的:
%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %‐5level
%logger{50} ‐ %msg%n
%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level
%logger{50} ‐ %msg%n
如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误no applicable action for [springProfile]
3.logback的配置文件参考
logback会依次读取以下类型配置文件:
- logback.groovy
- logback-test.xml
- logback.xml 如果均不存在会采用默认配置
logback组件之间的关系
- Logger:日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也
可以定义日志类型、级别。
- Appender:用于指定日志输出的目的地,目的地可以是控制台、文件、数据库等等。
- Layout:负责把事件转换成字符串,格式化的日志信息的输出。在logback中Layout对象被封
装在encoder中。
基本配置信息
System.err
${pattern}
FileAppender配置
System.err
${pattern}
${pattern}
${log_dir}/logback.log
%level%d{yyyy-MM-dd
HH:mm:ss}%c%M%L%thread%m
${log_dir}/logback.html
RollingFileAppender配置
System.err
${pattern}
${pattern}
${log_dir}/roll_logback.log
${log_dir}/rolling.%d{yyyy-MM-
dd}.log%i.gz
1MB
Filter和异步日志配置
System.err
${pattern}
${pattern}
${log_dir}roll_logback.log
${log_dir}rolling.%d{yyyy-MM-
dd}.log%i.gz
1MB
error
ACCEPT
6. 官方提供的log4j.properties转换成logback.xml
https://logback.qos.ch/translator/
3.3 logback-access的使用
logback-access模块与Servlet容器(如Tomcat和Jetty)集成,以提供HTTP访问日志功能。我们可以使
用logback-access模块来替换tomcat的访问日志。
1. 将logback-access.jar与logback-core.jar复制到$TOMCAT_HOME/lib/目录下
2. 修改$TOMCAT_HOME/conf/server.xml中的Host元素中添加:
3. logback默认会在$TOMCAT_HOME/conf下查找文件 logback-access.xml
DENY
4.log4j2的配置文件参考
Apache Log4j 2是对Log4j的升级版,参考了logback的一些优秀的设计,并且修复了一些问题,因此带来了一些重大的提升,主要有:
- 异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制。
- 性能提升, log4j2相较于log4j 和logback都具有很明显的性能提升,后面会有官方测试的数据。自动重载配置,参考了logback的设计,当然会提供自动刷新参数配置,最实用的就是我们在生产上可以动态的修改日志的级别而不需要重启应用。
- 无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制,避免频繁的日志收集
导致的jvm gc.
log4j2默认加载classpath下的 log4j2.xml 文件中的配置
D:/logs
4.3 Log4j2异步日志
异步日志
log4j2最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,我们来看看如何使用
log4j2的异步日志。
同步日志
5.log4j2的异步日志
log4j2最大的特点就是异步日志,其性能的提升主要也是从异步日志中受益,我们来看看如何使用log4j2的异步日志。
- 同步日志示意图
- 异步日志示意图
Log4j2提供了两种实现日志的方式,一个是通过AsyncAppender,一个是通过AsyncLogger,分别对应前面我们说的Appender组件和Logger组件。
注意:配置异步日志需要添加依赖:
com.lmax
disruptor
3.3.4
5.1. AsyncAppender方式
D:/logs
%d %p %c{1.} [%t] %m%n
5.2. AsyncLogger方式
AsyncLogger才是log4j2 的重头戏,也是官方推荐的异步方式。它可以使得调用Logger.log返回的更快。你可以有两种选择:全局异步和混合异步。
- 全局异步就是,所有的日志都异步的记录,在配置文件上不用做任何改动,只需要添加一个log4j2.component.properties 配置;
Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
- 混合异步就是,你可以在应用中同时使用同步日志和异步日志,这使得日志的配置方式更加灵活。
D:/logs
%d %p %c{1.} [%t] %m%n
如上配置: com.njit日志是异步的,root日志是同步的。
使用异步日志需要注意的问题:
- 如果使用异步日志,AsyncAppender、AsyncLogger和全局日志,不要同时出现。性能会和AsyncAppender一致,降至最低。
- 设置includeLocation=false ,打印位置信息会急剧降低异步日志的性能,比同步日志还要慢。