第一步 导入依赖
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
网友评论