SpringBoot中日志详解(一)

参考官方日志文档链接1
参考官方日志文档链接2
http://www.51gjie.com/javaweb/1096.html

1.日志框架基本介绍

常见的日志框架:JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j...

  • JCL(Jakarta Commons Logging) :spring 底层所使用的日志框架
  • JUL(java.util.logging) :java提供的日志框架,是JDK在1.4版本中引入的Java原生日志框架
  • Jboss-logging :就是jboss提供的日志框架(hibernate)
  • log4j :Apache的一个开源项目,可以控制日志信息输送的目的地是控制台、文件、GUI组件等,可以控制每一条日志的输出格式,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。虽然已经停止维护了,但目前绝大部分企业都是用的log4j。
  • logback :是由 Log4j 的作者设计完成的,拥有更好的特性,用来取代 Log4j 的一个日志框架,是 SLF4j 的原生实现
  • log4j2:已经不仅仅是 Log4j 的一个升级版本了,它从头到尾都被重写了。由于使用了 LMAX Disruptor 技术(无锁异步),使得日志的吞吐量、性能比 log4j 1.x 提高 10 倍,并解决了一些死锁的 bug,而且配置更加简单灵活。
  • slf4j(Simple Logging Facade for Java ):简单的日志框架,也是logback ,log4j 的作者写的,主要是目前日志的抽象层
日志门面 (日志的抽象层) 日志实现
JCL(Jakarta Commons Logging)、SLF4j(Simple Logging Facade for Java)、jboss-logging Log4j 、JUL(java.util.logging)、Log4j2 、Logback

2.springboot日志框架选择

SpringBoot 默认选择的是 SLF4J + Logback 的组合,本篇文章讲解的是默认的日志
在实际项目中我们可以整合 Log4j2 来代替原来的 Logback(形成 SLF4J + Log4j2 组合)。采用 Log4j2 有如下几个优点:

  • 相比与其他的日志系统,log4j2 丢数据的情况少;
  • 采用 disruptor 技术,在多线程环境下,性能高于 logback 等 10 倍以上(无论在同步日志模式还是异步日志模式下,在所有日志框架中 log4j2 性能都是最佳的);
  • 利用 jdk1.5 并发的特性,减少了死锁的发生;

3.日志级别

trace ⚠️:Logback does not have a FATAL level. It is mapped to ERROR.(Logback没有FATAL级别,映射到ERROR)

//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
    //日志的级别;
    //由低到高   trace

4.maven依赖


    org.springframework.boot
    spring-boot-starter-web

依赖关系

5.控制台输出基本介绍

2019-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2019-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2019-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

输出内容:
• 时间日期:精确到毫秒,易于排序
• 日志级别:ERROR, WARN, INFO, DEBUG ,TRACE
• 进程ID:图中45469
• 分隔符:--- 分隔符用于区分实际日志消息的开始
• 线程名:方括号括起来(在控制台输出时可能被截断,也就是展示不全)
• Logger名:通常使用源代码的类名(通常缩写)
• •日志消息

6.颜色配置

如果你的终端支持ANSI,彩色输出是用来帮助可读性。你可以设置spring.output.ansi.enabled来改变默认的自动检测(detect):设置值

  • ALWAYS
    开启彩色输出
  • DETECT
    尝试检测ANSI 颜色是否支持
  • NEVER
    关闭彩色输出

彩色编码使用%clr转换字配置,最简单的情势是根据日志级别进行色彩输出,例如:

%clr(%5p)

日志级别到颜色的映射:

Level Color
FATAL Red
ERROR Red
WARN Yellow
INFO Green
DEBUG Green
TRACE Green

你可以通过在转换器中提供选项来指定应当试用的色彩或风格。例如,为了使文本显示黄色:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

支持的颜色:
• blue
• cyan
• faint
• green
• magenta
• red
• yellow

7.SpringBoot修改日志的默认配置

① 设置日志级别

logging.level设置日志级别,后面跟生效的区域,比如root表示整个项目,也可以设置为某个包下,也可以具体到某个类名(日志级别的值不区分大小写)

#日志的最低输出级别调整,设置在com.xx包下
logging.level.com.xx=trace
#root日志以WARN级别输出(让日志只输出warn及以上级别的信息)
logging.level.root=warn
#springframework.web日志以DEBUG级别输出
logging.level.org.springframework.web=DEBUG
#hibernate日志以ERROR级别输出
logging.level.org.hibernate=ERROR

② 日志路径

# logging.path=
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
# logging.file=/usr/xx/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.file logging.path Example Description
(none) (none) 只在控制台输出
指定文件名 (none) my.log 输出日志到my.log文件(可以是绝对路径,也可以是相对路径)
(none) 指定目录 /var/log 输出到指定目录的 spring.log 文件中
指定文件名 指定目录 输出到文件名,前一个配置生效

当日志文件到达10Mb时会循环保存。文件的大小限制可通过logging.file.max-size属性设置。之前保存的日志文件会无限期存档,除非配置logging.file.max-history属性

③ 日志输出格式

%d:表示日期时间,
%thread:表示线程名,
%-5level:级别从左显示5个字符宽度,
%logger{50}:表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n:换行符

实例:%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

8.自定义日志配置

① 配置文件名称

在xml文件中,指定日志文件

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

建议将-spring变体用于日志记录配置(例如,logback-spring.xml而不是logback.xml)。如果使用标准配置位置,Spring将无法完全控制日志初始化
如果你既想完全掌控日志配置,但又不想用logback.xml作为Logback配置的名字,可以通过logging.config属性指定自定义的名字:

logging.config=classpath:logback-config.xml 
  • Spring Boot包含了许多可以帮助进行高级配置的Logback扩展,您可以在logback-spring.xml配置文件中使用这些扩展名
  • 由于标准的logback.xml配置文件加载的太早,所以你不能在里面使用扩展部分,您需要使用logback-spring.xml或定义一个logging.config属性

② springProfile标签针对不同开发环境

使用标签,您可以根据活动的Spring配置文件选择包括或排除配置部分


    



    



    

③ Environment Properties

标签允许您公开来自Spring环境的属性,以便在Logback中使用。如果要从application.properties中访问文件中的值,这样做很有用。该标签的工作方式与Logback的标签类似。但是,不是指定直接的值value,而是指定属性的源source(来自Environment)。如果需要将该属性存储在局部作用域之外的其他地方,则可以使用scope属性。如果需要回退值(在Environment中没有设置该属性的情况下),可以使用defaultValue属性。以下示例显示如何公开用于Logback的属性



    ${fluentHost}
    ...

④ 配置详解




    
    logback
    
    
    
    

    
    

    

    
    
        
        
            debug
        
        
        
            
            %d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{50} - %msg%n
            
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %blue(%logger{50}) - %highlight(%msg) %n
            
            UTF-8
        
    

    
    
        
        ${LOG_PATH}/info.log
        
        
        
            
            ${LOG_PATH}/info.%d{yyyy-MM-dd}.%i.log
            
            15
            
            10MB
            
            1GB
        

       
       
       
            ${LOG_PATH}/info.%d{yyyy-MM-dd}.%i.log
            15
            1GB

            
                100MB
            
        

        

        
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            
            UTF-8
        

        
        
            
            INFO
            
            ACCEPT
            
            DENY
        
    
    
    
    
        
        
    
    
    
    
    
    
    
        
    
 

root 指定的日志级别就是用类进行输出的日志,例如:

private static Logger log = LoggerFactory.getLogger(logbackTest.class);

⑤ loger的使用:

public class TestController {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @GetMapping("/show")
    public void show() {
        logger.trace("这是trace日志...");
        logger.debug("这是debug日志...");
        logger.info("这是info日志...");
        logger.warn("这是warn日志...");
        logger.error("这是error日志...");
    }
}

    

  • 第一种:带有loger的配置,不指定级别,不指定appender

将控制demo包下的所有类的日志的打印,但是并没用设置打印级别,所以继承他的上级的日志级别,即root的级别“info”;
没有设置addtivity,默认为true,将此loger的打印信息向上级传递,设置为false时候,执行/show,show()方法执行,但是不打印日志信息;
没有设置appender,此loger本身不打印任何信息。
当执行该包下的某个类中的功能时,将方法内所有日志信息传递给root,本身并不打印;
root接到下级传递的信息,交给已经配置好的名为“console”的appender处理,“console”appender将信息打印到控制台。

此配置类似:

结果:
2020-10-09 15:03:57.680 logback [http-nio-8080-exec-1] INFO  com.mine.demo.TestDemoController - 这是info日志...
2020-10-09 15:03:57.680 logback [http-nio-8080-exec-1] WARN  com.mine.demo.TestDemoController - 这是warn日志...
2020-10-09 15:03:57.681 logback [http-nio-8080-exec-1] ERROR com.mine.demo.TestDemoController - 这是error日志...

当additivity=false时候,本身打印,但是没有设置appender,此loger本身不打印任何信息。
  • 第二种:带有多个loger的配置,指定级别,指定appender

    

控制com.mine.demo.TestDemoController类的日志打印,打印级别为“WARN”;
additivity属性为false,表示此loger的打印信息不再向上级传递;
指定了名字为“console”的appender;
当执行TestDemoController中的方法时将级别为“WARN”及大于“WARN”的日志信息交给此loger指定的名为“console”的appender处理,在控制台中打出日志,不再向上级root传递打印信息。

结果:
2020-10-09 14:42:19.792 logback [http-nio-8080-exec-1] WARN  com.mine.demo.TestDemoController - 这是warn日志...
2020-10-09 14:42:19.792 logback [http-nio-8080-exec-1] ERROR com.mine.demo.TestDemoController - 这是error日志...


    


多个个同时存在时候,后一个覆盖前一个,level,additivity,appender后一个有则覆盖,没有则使用前一个配置,所以上面的level="debug", additivity="false", 

结果:
2020-10-09 15:03:57.680 logback [http-nio-8080-exec-1] INFO  com.mine.demo.TestDemoController - 这是info日志...
2020-10-09 15:03:57.680 logback [http-nio-8080-exec-1] WARN  com.mine.demo.TestDemoController - 这是warn日志...
2020-10-09 15:03:57.681 logback [http-nio-8080-exec-1] ERROR com.mine.demo.TestDemoController - 这是error日志...


    


    

结果:
2020-10-09 15:30:12.696 logback [http-nio-8080-exec-1] INFO  com.mine.demo.TestDemoController - 这是info日志...
2020-10-09 15:30:12.696 logback [http-nio-8080-exec-1] INFO  com.mine.demo.TestDemoController - 这是info日志...
2020-10-09 15:30:12.698 logback [http-nio-8080-exec-1] WARN  com.mine.demo.TestDemoController - 这是warn日志...
2020-10-09 15:30:12.698 logback [http-nio-8080-exec-1] WARN  com.mine.demo.TestDemoController - 这是warn日志...
2020-10-09 15:30:12.698 logback [http-nio-8080-exec-1] ERROR com.mine.demo.TestDemoController - 这是error日志...
2020-10-09 15:30:12.698 logback [http-nio-8080-exec-1] ERROR com.mine.demo.TestDemoController - 这是error日志...

开始理解的时候是本身打印info级别,向上级root传递的时候,上级是warn级别的,所以打印是本身打印info级别以上的,上级只打印筛选的warn级别以上的。结果多次测试发现不是这样。
后来理解:当本身的打印日志信息传递给上级,上级只负责输出。所以当本身打印info日志,向上级root传递info信息,上级继续打印info日志;打印warn日志......依次类推

9.最终配置logback.xml



    
    

    
    
        
            debug
        
        
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8
        
    

    
    
        ${log_path}/info.log
        
            15
            10MB
            2GB
        

        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8
        
        
            info
            ACCEPT
            DENY
        
    

    
        ${log_path}/error.log
        
            %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            UTF-8
        
        
            ${log_path}/error.%d{yyyy-MM-dd}.%i.log
            
                100MB
            
            15
            2GB
        
        
        
            ERROR
            ACCEPT
            DENY
        
    

    
        
            
        
        
    

    
        
            
            
            
        
    

你可能感兴趣的:(SpringBoot中日志详解(一))