springboot-logback 整合避坑

第一步 导入依赖

spring-boot-starter-web已经包含了logback,所以无需添加maven依赖

第二步 配置官方提供的logback-spring.xml

这里不做配置内容介绍,官方复制粘贴进项目resource目录下即可,算了我贴出来吧

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->

<!-- 参考文章 https://www.cnblogs.com/zhangjianbing/p/8992897.html -->
<configuration scan="true" scanPeriod="10 seconds">

    <contextName>logback</contextName>

    <!-- 设置属性,文件中使用 ${} 获取属性值 -->
    <!-- 项目名称 -->
    <springProperty scope="context" name="projectName" source="spring.application.name"/>
    <!-- 日志存放目录;默认从配置文件中读取 "log.path" 的配置值,若没有配置,使用默认值 /var/yuemia-live-logs/ -->
    <springProperty scope="context" name="logPath" source="log.path" defaultValue="D:\workspace\2021-spring-test\broadcast-log"/>
    <!-- 日志级别;默认从配置文件中读取 "logging.level.root" 的配置值,若没有配置,使用默认值 info -->
    <springProperty scope="context" name="logging.level.root" source="logging.level.root" defaultValue="info"/>

    <!--log日志格式-->
    <property name="PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>


    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${logging.level.root}</level>
        </filter>
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>


    <!--输出到文件-->
    <!-- DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/${projectName}/log_debug.log</file>
        <encoder>
            <pattern>${PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志输出文件名路径 -->
            <fileNamePattern>${logPath}/${projectName}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/${projectName}/log_info.log</file>
        <encoder>
            <pattern>${PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${projectName}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/${projectName}/log_warn.log</file>
        <encoder>
            <pattern>${PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${projectName}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>


    <!-- ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/${projectName}/log_error.log</file>
        <encoder>
            <pattern>${PATTERN}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logPath}/${projectName}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天数-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
        <!-- 此日志文件只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!--
        root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
        level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
        不能设置为INHERITED或者同义词NULL。默认是DEBUG
        可以包含零个或多个元素,标识这个appender将会添加到这个logger。

        nico:设置level级别后,磁盘上低级别的日志文件里没有任何内容,控制台也是一样不会输出
    -->
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="DEBUG_FILE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    </root>
</configuration>

第三步 启动

启动后一切正常 查看配置的路径下有没有日志文件生成


图片.png

有日志文件生成没问题


图片.png
第四步 踩坑

有没有发现怎么会有两个文件夹,另一个看起来还有点怪,projectName_IS_UNDEFINED这是一个什么东西,不是我想要的。注意:此时我的配置文件是application.yml,这是一个坑,让我慢慢道来。那么我想重命名一下这个配置文件名,现在为logback-spring.xml修改成logback-broadcast.xml可以不?

logging:
  config: classpath:logback-broadcast.xml

当然可以 application.yml加入上面的配置就可以在启动时找到这个文件,但是能不能正常启动?

Caused by: java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.classic.joran.action.ContextNameAction - Failed to rename context [nacos] as [logback] java.lang.IllegalStateException: Context has been already given a name

好吧,报错了,这完全不正常啊,别人这么配置完全没问题的啊。

public class BroadcastCastApplication {
    public static void main(String[] args) {

        /**
         * 禁用 Spring Cloud Context,要不然会导致 logback-spring.xml会被加载两次
         * #yml中配置logging config与path必须同时配置 否则无法启动 参考http://www.itersblog.com/archives/5.html
         * Spring Cloud Context 详情:https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html
         * System.setProperty("spring.cloud.bootstrap.enabled", "false");
         */
        System.setProperty("spring.cloud.bootstrap.enabled", "false");
        SpringApplication.run(BroadcastCastApplication.class, args);
    }
}

百度后,在启动类上加 System.setProperty("spring.cloud.bootstrap.enabled", "false");,然后启动是没问题的


图片.png

生成的日志文件看起来很舒服,没有奇奇怪怪的东西。


图片.png

这样好像解决了问题,但是我看别人也没这么麻烦啊,启动类里也没修改就可以正常启动的啊,那是配置文件不一样,你用的是application.yml,别人用的bootstrap.yml,好吧试试看,替换成bootstrap.yml后,去掉启动类中的System.setProperty("spring.cloud.bootstrap.enabled", "false")这一行代码,运行


图片.png

好的没问题,得到了想要的结果

总结:如果用application.yml配置logback的配置文件和日志存放路径那么,必须修改启动类里的那个配置代码,反之使用bootstrap.yml不影响。
原因: logback-spring.xml 启动时会被读取两遍, 因为 Spring Cloud 程序有两个上下文,用application.yml会产生冲突,使用bootstrap.yml则不会。
参考:https://blog.csdn.net/num_zero_0/article/details/105069940

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容