SpringBoot——⽇志及原理
⼀、SpringBoot ⽇志
选⽤ SLF4j (接⼝)和 logback (实现类),除了上述⽇志框架,市场上还存在 JUL(java.util.logging)、JCL(Apache Commons Logging)、Log4j 、Log4j2、SLF4j 、jboss-logging 等。SpringBoot 在框架内部使⽤JCL ,SpringBoot 的 spring-boot-starter-logging 采⽤了 SLF4j+logback 的形式,SpringBoot 也能⾃动适配(jul 、log4j2、logback )并简化配置。其实 logback 是 log4j 的升级版,因为 log4j 在性能上有缺陷(因为log4j 在多线程情况下,会竞争 Logger 的锁),且 SLF4j 也是 logback 的开发者开发的⼀个⽇志接⼝(⽇志门⾯)。
⽇志门⾯
⽇志实现JCL (Jakarta Commons Logging )
SLF4J (Simple Logging Facade for Java )
Jobss-logging Log4j JUL (Java Util Logging )Log4j2Logback
⼆、SLF4j 使⽤
【1】以后开发的时候,⽇志记录⽅法的调⽤,不应该来直接调⽤⽇志的实现类,⽽是调⽤⽇志抽象类层⾥⾯的⽅法。
● 给系统⾥⾯导⼊ slf4j 的 jar 和 logback 的实现 jar ,Java 类中的使⽤如下所⽰:很常⽤
1 import  org.slf4j.Logger;
2 import  org.slf4j.LoggerFactory;
3
4 public  class  HelloWorld {
5  public  static  void  main(String[] args) {
6    Logger logger = Logger(HelloWorld.class );//记录器
7    logger.info("Hello World");
8  }
9 }
● 根据 SLF4J 抽象类,提供实现类的时候,SLF4j 官⽅提供的配置逻辑如下所⽰,有的需要加⼊整合的jar
包。
注意:每⼀个⽇志的实现框架都有⾃⼰的配置⽂件。使⽤ slf4j 以后,配置⽂件还是做成⽇志实现框架⾃⼰本⾝的配置⽂件。
【2】常见问题:同⼀个系统中,包涵多种框架可能就会使⽤多种⽇志记录(slf4j+logback )、Spring (commons-logging )、Hibernate (Jboss-logging )、MyBatis 等,如果我们要统⼀使⽤slf4j 记录⽇志,思想如下:
✔  将系统中其他⽇志框架先排除出去;
✔  ⽤中间包替换原有的⽇志框架;
✔  我们导⼊ slf4j 唯⼀⽇志的实现;具体可见下⽅,官⽅给出的图解:
三、Spring Boot⽇志关系
测试 springBoot 的⽇志使⽤,⾸先引⼊⽇志的 starter启动器。
☞⾸先我们查看下 l中的依赖关系:右键——>Diagrams——>
☞可以查看到我们我们使⽤最多的启动器:spring‐boot‐starter
1<dependency>
2<groupId>org.springframework.boot</groupId>
3<artifactId>spring‐boot‐starter</artifactId>
4</dependency>
☞⽽我们使⽤的⽇志启动器 spring‐boot‐starter‐logging 依赖于 spring‐boot‐starter,SpringBoot 使⽤它来做⽇志功能:
1<dependency>
2<groupId>org.springframework.boot</groupId>
3<artifactId>spring‐boot‐starter‐logging</artifactId>
4</dependency>
☞⽽spring‐boot‐starter‐logging 启动器的底层依赖实现关系如下:
总结:1)、SpringBoot 底层也是使⽤ slf4j+logback 的⽅式进⾏⽇志记录的。
2)、SpringBoot 也考虑到了其他⽇志,将他们都替换成了 slf4通过替换包。
3)、中间替换包?我们通过引⼊的jar包查看究竟:
4)、如果我们引⼊了其他框架?⼀定要把这个框架的默认⽇志依赖移除掉。我们点进 spring‐boot‐starter‐logging 会发现如下SpringBoot 引⼊ springframework 依赖时⾃动排除了 commons-logging 依赖,避免冲突,我们也应如此。
1<dependency>
2<groupId>org.springframework</groupId>
3<artifactId>spring‐core</artifactId>
4<exclusions>
5<exclusion>
6<groupId>commons‐logging</groupId>
7<artifactId>commons‐logging</artifactId>
8</exclusion>
9</exclusions>
10</dependency>
总结:SpringBoot 能够⾃动适配所有的⽇志,⽽且底层使⽤ slf4j+logback 的⽅式记录⽇志,引⼊其他框架的时候,只需要把这个框架依赖的⽇志框架排除掉。
四、⽇志使⽤
【1】默认配置:SpringBoot 已经帮我们配置好了⽇志,⽇志级别=info。
1 //⽇志记录器
2 Logger logger = Logger(getClass());
3
4 @Test
5 public void contextLoads() {
6    //⽇志的级别:优先级trace<debug<info<warn<error
7    //可以调整输出的⽇志级别;⽇志就只会在这个级别及以后的⾼级别⽣效
8    ace("这是跟踪⽇志");
9    logger.debug("这是调试⽇志");
10    //SpringBoot默认使⽤的是 info级别的;root级别
11    logger.info("这是⾃定义");
12    logger.warn("这是警告⽇志");
13    ("这是错误⽇志");
14}
【2】修改⽇志级别,可以细化到给包分配级别,配置⽂件中配置如下:
1 #修改打印级别 == 可以细化到包级别
2 logging.level=trace
3 #下⾯path与file都不指定时,⽇志输出到控制台,两个都指定时,file⽣效
4 #指定⽬录,⽂件名默认spring.log中,如下是在当前磁盘根路径下创建var⽂件和⾥⾯的log⽂件。
5 logging.path=/var/log
6 #指定⽂件名当前项⽬下⽣成springboot.log⽇志,也可以指定到本地⽂件中d:/springboot.log等
7 logging.file=springboot.log
8 #在控制台⽇志输⼊的格式
9 sole=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n
10 #在⽂件中⽇志输出的格式
11 #⽇志输出格式:
12 #    %d表⽰⽇期时间,
13 #    %thread表⽰线程名,
14 #    %‐5level:级别从左显⽰5个字符宽度
15 #    %logger{50} 表⽰logger名字最长50个字符,否则按照句点分割。
16 #    %msg:⽇志消息,
17 #    %n是换⾏符
18 logging.pattern.file=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n
【3】SpringBoot 的默认⽇志配置位于 spring-boot-1.5.17.RELEASE.jar:org.springframework.boot:logging ⽂件,例如查看logback ⽂件夹中的 l 和 l。 1<!-- l部分内容 -->
2<included>
3<include resource="org/springframework/boot/logging/l"/>
4<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${pdir:-/tmp}}}/spring.log}"/>
5<include resource="org/springframework/boot/logging/l"/>
6<include resource="org/springframework/boot/logging/l"/>
7<!-- 默认级别 -->
8<root level="INFO">
9<appender-ref ref="CONSOLE"/>
10<appender-ref ref="FILE"/>
11</root>
12</included>
【4】如果觉得⽇志配置不够⽤,客户可以⾃⼰指定配置:给类路径下(resource)放每个⽇志框架⾃⼰定义的配置⽂件即可(如下名称的⽇志⽂件),这样 SpringBoot 就不适⽤默认配置。可以参考 SpringBoot 官⽹中的 logging模块。
●例如创建如上的 l 放⼊ resource中,将会直接被⽇志框架直接识别了。内容如下,作为参考:
1<?xml version="1.0" encoding="UTF-8"?>
2<!--
3scan:当此属性设置为true时,配置⽂件如果发⽣改变,将会被重新加载,默认值为true。
4scanPeriod:设置监测配置⽂件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性⽣效。默认的时间间隔为1分钟。
5debug:当此属性设置为true时,将打印出logback内部⽇志信息,实时查看logback运⾏状态。默认值为false。
6-->
7<configuration scan="false" scanPeriod="60 seconds" debug="false">
8<!-- 定义⽇志的根⽬录 -->
9<property name="LOG_HOME" value="/app/log"/>
10<!-- 定义⽇志⽂件名称 -->
11<property name="appName" value="atguigu-springboot"></property>
12<!-- ch.ConsoleAppender 表⽰控制台输出 -->
13<appender name="stdout" class="ch.ConsoleAppender">
14<!--
15⽇志输出格式:
16            %d表⽰⽇期时间,
17            %thread表⽰线程名,
18            %-5level:级别从左显⽰5个字符宽度
19            %logger{50} 表⽰logger名字最长50个字符,否则按照句点分割。
20            %msg:⽇志消息,
21            %n是换⾏符
22-->
23<layout class="ch.qos.logback.classic.PatternLayout">
24<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
25</layout>
26</appender>
27
28<!-- 滚动记录⽂件,先将⽇志记录到指定⽂件,当符合某个条件时,将⽇志记录到其他⽂件 -->
29<appender name="appLogAppender" class="ch.olling.RollingFileAppender">
30<!-- 指定⽇志⽂件的名称 -->
31<file>${LOG_HOME}/${appName}.log</file>
32<!--
33当发⽣滚动时,决定 RollingFileAppender 的⾏为,涉及⽂件移动和重命名
34        TimeBasedRollingPolicy:最常⽤的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
35-->
36<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
37<!--
38滚动时产⽣的⽂件的存放位置及⽂件名称 %d{yyyy-MM-dd}:按天进⾏⽇志滚动
39            %i:当⽂件⼤⼩超过maxFileSize时,按照i进⾏⽂件滚动
40-->
41<fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
42<!--
43可选节点,控制保留的归档⽂件的最⼤数量,超出数量就删除旧⽂件。假设设置每天滚动,
44且maxHistory是365,则只保存最近365天的⽂件,删除之前的旧⽂件。注意,删除旧⽂件是,
45那些为了归档⽽创建的⽬录也会被删除。log4j与log4j2
46-->
47<MaxHistory>365</MaxHistory>
48<!--
49当⽇志⽂件超过maxFileSize指定的⼤⼩是,根据上⾯提到的%i进⾏⽇志⽂件滚动注意此处配置SizeBasedTriggeringPolicy是⽆法实现按⽂件⼤⼩进⾏滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy 50-->
51<timeBasedFileNamingAndTriggeringPolicy class="ch.olling.SizeAndTimeBasedFNATP">
52<maxFileSize>100MB</maxFileSize>
53</timeBasedFileNamingAndTriggeringPolicy>
54</rollingPolicy>
55<!-- ⽇志输出格式: -->
56<layout class="ch.qos.logback.classic.PatternLayout">
57<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
58</layout>
59</appender>
60
61<!--
62        logger主要⽤于存放⽇志对象,也可以定义⽇志类型、级别
63        name:表⽰匹配的logger类型前缀,也就是包的前半部分
64        level:要记录的⽇志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
65        additivity:作⽤在于children-logger是否使⽤ rootLogger配置的appender进⾏输出,
66        false:表⽰只⽤当前logger的appender-ref,true:
67表⽰当前logger的appender-ref和rootLogger的appender-ref都有效
68-->
69<!-- hibernate logger -->
70<logger name="com.atguigu" level="debug"/>
71<!-- Spring framework logger -->
72<logger name="org.springframework" level="debug" additivity="false"></logger>
73
74<!--
75    root与logger是⽗⼦关系,没有特别定义则默认为root,任何⼀个类只会和⼀个logger对应,
76要么是定义的logger,要么是root,判断的关键在于到这个logger,然后判断这个logger的appender和level。
77-->
78<root level="info">
79<appender-ref ref="stdout"/>
80<appender-ref ref="appLogAppender"/>
81</root>
82</configuration>
●当命名中带有 spring 时,例如:l:⽇志框架就不直接加载⽇志的配置项,由 SpringBoot解析⽇志配置,但可以使⽤ SpringBoot的⾼级 springProfile功能,
如下配置。如果不带 spring使⽤ springProfile标签时就会出错。
1<layout class="ch.qos.logback.classic.PatternLayout">
2<!-- 可以指定以哪种形式运⾏环境 -->
3<springProfile name="dev">
4<pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %‐5level%logger{50} ‐ %msg%n</pattern>
5</springProfile>
6<springProfile name="!dev">
7<pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level%logger{50} ‐ %msg%n</pattern>
8</springProfile>
9</layout>
五、切换⽇志框架
根据官⽅⽂档如下配置:可以看出⾸先排除 logging启动器,依赖 log4j2的启动器即可。(排除:可以通过 l的依赖视图,右键Exclude)
1<dependency>
2<groupId>org.springframework.boot</groupId>
3<artifactId>spring-boot-starter-web</artifactId>
4</dependency>
5<dependency>
6<groupId>org.springframework.boot</groupId>
7<artifactId>spring-boot-starter</artifactId>
8<exclusions>
9<exclusion>
10<groupId>org.springframework.boot</groupId>
11<artifactId>spring-boot-starter-logging</artifactId>
12</exclusion>
13</exclusions>
14</dependency>
15<dependency>
16<groupId>org.springframework.boot</groupId>
17<artifactId>spring-boot-starter-log4j2</artifactId>
18</dependency>
六、按天分类⽇志
1<!--按天⽣成⽇志-->
2<appender name="logFile" class="ch.olling.RollingFileAppender">
3<Prudent>true</Prudent>
4<rollingPolicy class="ch.olling.TimeBasedRollingPolicy">
5<FileNamePattern> applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log </FileNamePattern> 6</rollingPolicy>
7<layout class="ch.qos.logback.classic.PatternLayout">
8<Pattern> %d{yyyy-MM-dd HH:mm:ss} -%msg%n </Pattern>
9</layout>
10</appender>

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。