当前位置:   article > 正文

Spring Boot logback日志_error in ch.qos.logback.core.joran.action.nestedco

error in ch.qos.logback.core.joran.action.nestedcomplexpropertyia - could no

slf4j和log4j、log4j2、logback 之间的关系

  • log4j出来时就得到了广泛的应用,是Java日志事实上的标准,并成为了Apache的项目
  • Apache要求把log4j并入到JDK,SUN拒绝,并在jdk1.4版本后增加了JUL(java.util.logging)
  • 毕竟是JDK自带的,JUL也有很多人用。同时还有其他日志组件,如SimpleLog等。这时如果有人想换成其他日志组件,如log4j换成JUL,因为api完全不同,就需要改动代码。
  • Apache见此,开发了JCL(Jakarta Commons Logging),即commons-logging-xx.jar。它只提供一套通用的日志接口api,并不提供日志的实现。这样应用程序可以在运行时选择自己想要的日志实现组件。
  • 这样看上去也挺美好的,但是log4j的作者觉得JCL不好用,自己开发出slf4j,它跟JCL类似,本身不替供日志具体实现,只对外提供接口或门面。目的就是为了替代JCL。同时,还开发出logback,一个比log4j拥有更高性能的组件,目的是为了替代log4j。
  • Apache参考了logback,并做了一系列优化,推出了log4j2。

所以目前我们主要用到的日志框架为logback和log4j2。而且二者都支持slf4j规范。比如我们的spring boot就是使用slf4j+logback作为默认的日志方案。

所以,在我们的项目代码中,请大家引入slf4j包的对象,这样可以让我们更方便的做日志框架的切换等操作。

logback简介

本文只做logback的常用功能讨论,更多需求请查看logback官方参考文档
logback 分为三个模块,logback-core、logback-classic 和 logback-access。Logback-classic 原生实现了SLF4J API。logback有如下几个重要的组件。

Appender

我们可以叫他记录器。负责输出日志。通常我们会为它配置Layout或Encoder

  1. ConsoleAppender 输出到控制台的记录器
  2. FileAppender 输出到文件的记录器,但我们通常会使用它的子类RollingFileAppender
  3. RollingFileAppender 滚动日志记录器。可以指定每个日志文件的最大大小以及定期的日志删除策略。

输出到控制台示例

其实spring Boot 默认就配置了logback日志的,而且控制台打印出来还有颜色,而且布局也很整齐。这个我们后面再说,我们先来个示例看看。
在resource目录新建logback-spring.xml配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
debug="true" 表示启用logback的日志检查,也就是spring Boot的banner上面的部分日志
-->
<configuration debug="true">

    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>
                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <!--
        name:用来指定受此loger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别(日志级别),大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
            还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
        addtivity:是否向上级loger传递打印信息。默认是true。
        这里配置logger的上级为root,logger没有配置appender,那么将会使用root配置的appender打印
     -->
    <logger name="com.yyoo" level="DEBUG" />

    <!-- OFF 为关闭日志输出,当然我们也可以设置为ERROR -->
    <root level="OFF">
        <appender-ref ref="STDOUT" />
    </root>

</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

注:使用logback-spring.xml而不是logback.xml。因为logback-spring.xml支持很多Spring boot的扩展,而logback.xml加载过早,导致无法支持这些扩展。

启动日志如下

16:10:14,916 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
16:10:14,918 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
16:10:14,922 |-INFO in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Assuming default type [ch.qos.logback.classic.encoder.PatternLayoutEncoder] for [encoder] property
16:10:14,936 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.yyoo] to DEBUG
16:10:14,937 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@2b4bac49 - Propagating DEBUG level on Logger[com.yyoo] onto the JUL framework
16:10:14,938 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to OFF
16:10:14,938 |-INFO in ch.qos.logback.classic.jul.LevelChangePropagator@2b4bac49 - Propagating OFF level on Logger[ROOT] onto the JUL framework
16:10:14,938 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
16:10:14,938 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
16:10:14,938 |-INFO in org.springframework.boot.logging.logback.SpringBootJoranConfigurator@4470f8a6 - Registering current configuration as safe fallback point

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.6.1)

16:10:14.994 [main] INFO  com.yyoo.springmvc.Appliction - Starting Appliction using Java 1.8.0_181 on ZHOU with PID 13028 (D:\work\code\mytest\springmvc\target\classes started by zhou in D:\work\code\mytest\springmvc)
16:10:14.996 [main] DEBUG com.yyoo.springmvc.Appliction - Running with Spring Boot v2.6.1, Spring v5.3.13
16:10:14.996 [main] INFO  com.yyoo.springmvc.Appliction - No active profile set, falling back to default profiles: default
16:10:16.033 [main] INFO  com.yyoo.springmvc.Appliction - Started Appliction in 1.364 seconds (JVM running for 1.941)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

到此你会发现,现在打印没有颜色了,而且日志格式好像也不太整齐了,别着急,我们来看看spring Boot中的logback默认的日志文件。

在spring-boot.x.x.x.jar包中可以找到spring对logback的功能增强的配置
在这里插入图片描述
其中defaults.xml中就配置了支持在控制台打印有颜色的日志。我们不用重新定义或者拷贝,直接include即可。(注意:其实如果我们没有自定义配置logback-spring.xml那么springboot默认就使用的如下的配置)

<?xml version="1.0" encoding="UTF-8"?>
<!--
debug="true" 表示启用logback的日志检查,也就是spring Boot的banner上面的部分日志
-->
<configuration debug="false">
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <appender name="STDOUT"
              class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>
                ${CONSOLE_LOG_PATTERN}
            </pattern>
        </encoder>
    </appender>

    <!--
        name:用来指定受此loger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别(日志级别),大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
            还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
        addtivity:是否向上级loger传递打印信息。默认是true。
        这里配置logger的上级为root,logger没有配置appender,那么将会使用root配置的appender打印
     -->
    <logger name="com.yyoo" level="DEBUG" />

    <!-- OFF 为关闭日志输出,当然我们也可以设置为ERROR -->
    <root level="OFF">
        <appender-ref ref="STDOUT" />
    </root>

</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

CONSOLE_LOG_PATTERN是defaults.xml里配置的名称,你如果需要修改,就自行配置把。

输出到文件

上图file-appender.xml就是默认的spring配置输出到文件,如果我们没有特殊的需要,我们可以直接include使用即可。这个这里就不说了。

Spring中直接配置

默认配置已经支持大部分都情况了,意味着其实我们可以不用自定义配置的,而且spring Boot默认的配置是支持我们在properties文件中配置的,对应的配置属性如下

properties配置logback中的配置项说明
logging.exception-conversion-wordLOG_EXCEPTION_CONVERSION_WORD记录异常时使用的转换字。
logging.file.nameLOG_FILE如果定义,则在默认日志配置中使用。
logging.file.pathLOG_PATH如果定义,则在默认日志配置中使用。
logging.pattern.consoleCONSOLE_LOG_PATTERN要在控制台 (stdout) 上使用的日志模式。
logging.pattern.dateformatLOG_DATEFORMAT_PATTERN日志日期格式的 Appender 模式。
logging.charset.consoleCONSOLE_LOG_CHARSET用于控制台日志记录的字符集。
logging.pattern.fileFILE_LOG_PATTERN要在文件中使用的日志模式(如果LOG_FILE已启用)。
logging.charset.fileFILE_LOG_CHARSET用于文件记录的字符集(如果LOG_FILE已启用)。
logging.pattern.levelLOG_LEVEL_PATTERN呈现日志级别时使用的格式(默认%5p)。

以下是使用logback日志特有的配置

properties配置logback中的配置项说明
logging.logback.rollingpolicy.file-name-patternLOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN滚动日志文件名的模式(默认${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)。此配置会影响后面的滚动删除策略,请搞清楚了再自定义配置。比如%i会影响归档文件的数量。日期格式会也会影响。
logging.logback.rollingpolicy.clean-history-on-startLOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START是否在启动时清除存档日志文件,默认false。此配置不影响下面的最大归档和总大小删除策略。
logging.logback.rollingpolicy.max-file-sizeLOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE最大日志文件大小。默认无限制
logging.logback.rollingpolicy.total-size-capLOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP要保留的日志备份的总大小。默认无限制
logging.logback.rollingpolicy.max-historyLOGBACK_ROLLINGPOLICY_MAX_HISTORY要保留的最大归档日志文件数。默认无限制

springProfile标签

在配置中,我们可以添加springProfile标签来区分不同的部署环境使用不同的日志配置。

<springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>

    <springProfile name="test">
        <root level="INFO">
            <appender-ref ref="FILE" />
        </root>
    </springProfile>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

如上表示,dev环境只打印到控制台,test环境只打印到日志文件。

注意springProfile要结合profile的配置。而springBoot的profile还可以结合maven打包。请查看maven的profile和Spring boot 的profile整合

总结

综上,我们可以自定义一个logback-spring.xml文件,即可以使用spring Boot增强的带颜色打印到控制台的功能,又能够自己扩展一些配置。

<?xml version="1.0" encoding="UTF-8"?>
<!--
debug="true" 表示启用logback的日志检查,也就是spring Boot的banner上面的部分日志
-->
<configuration debug="false">
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />

    <!-- 打印sql日志,当然这里你也可以添加其他如jpa或Hibernate的日志DEBUG -->
    <logger name="org.apache.ibatis" level="DEBUG"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>

    <!--
        name:用来指定受此loger约束的某一个包或者具体的某一个类。
        level:用来设置打印级别(日志级别),大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
            还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。
        addtivity:是否向上级loger传递打印信息。默认是true。
        这里配置logger的上级为root,logger没有配置appender,那么将会使用root配置的appender打印
     -->
    <logger name="com.yyoo" level="DEBUG" />

    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>

    <springProfile name="test">
        <root level="INFO">
            <appender-ref ref="FILE" />
        </root>
    </springProfile>

</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

文件大部分拷贝上面图中的base.xml文件。

默认情况下,Spring Boot 只记录到控制台,不写入日志文件。如果你想在控制台输出之外写入日志文件,你需要配置properties文件属性logging.file.name和logging.file.path

slf4j API的使用

建议在代码中使用slf4j的api,这有助于我们在之后更换其他日志框架时可以不用修改代码,前面已经提到slf4j是日志门面,我们也可以认为是日志的标准接口,logback和log4j2等常用的日志框架都适配了该接口门面。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("logback")
public class DemoController {

    private final Logger log = LoggerFactory.getLogger(DemoController.class);

    @RequestMapping("test1")
    public void test1(){
        try{
            int a = 1/0;
        }catch (Exception e){
            log.debug("出现异常{},打印日志","参数1",e);
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

示例中debug方法的参数有多个,第一个为消息模板,{}为占位符,按顺序第二个参数对应第一个占位符,如果要传Exception对象,那么该对象必须是最后一个参数。

以上的log对象每次都要在对应的类中定义,比较麻烦。但是如果定义一个公共的log类,日志打印出来的记录位置都是同一个地址,不方便排查。此时我们可以使用Lombok的@Slf4j注解来解决关于Lombok我们将在后面介绍。

上一篇:Spring Boot配置绑定
下一篇:Spring Boot 任务调度

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/312837
推荐阅读
相关标签
  

闽ICP备14008679号