每一个成功人士的背后,必定曾经做出过勇敢而又孤独的决定。
放弃不难,但坚持很酷~
logback 是一个开源的日志组件,由三个部分组成:logback-core,logback-classic,logback-access。其中 logback-core 是其他两个模块的基础。
在 spring boot 中,由于 spring-boot-starter-web 和 spring-boot-starter-logging 是有依赖关系的,所以只需要引入 spring-boot-starter-web 就可以使用 logback 框架了。
logback 中有几个常用标签:
property、appender,encoder、filter、rollingPolicy、logger、root 等,下文会有详细介绍。
spring boot 会默认加载 logback-spring.xml 文件,如果自定义配置名称(logback-test.xml)的话,可在 application.xml 文件内添加:
logging:
config: classpath:logback-test.xml
先来看一下配置大概:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
...
</configuration>
configuration 标签有三个属性:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 19:34:48.934 [http-nio-8081-exec-1] WARN com.study.spring.helloDemo - warn warn warn warn warn warn warn warn -->
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
<!-- 编码 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<encoder> 表示对日志输出进行编码:
按日志级别输出到文件,将 error 级别的日志与其它级别的日志进行分离:
<!--定义日志文件的存储位置-->
<property name="LOG_PATH" value="E://logs"/>
<property name="LOG_INFO_FILE" value="info.log"/>
<property name="LOG_ERROR_FILE" value="error.log"/>
<!--除去error级别的日志文件输出-->
<appender name="FILE-INFO-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果是true,日志被追加到文件结尾,如果是false,清空现存文件,默认是true。-->
<append>true</append>
<file>${LOG_PATH}/info/${LOG_INFO_FILE}}</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--设置过滤的日志级别-->
<level>ERROR</level>
<!--符合该日志级别的,拒绝-->
<onMatch>DENY</onMatch>
<!--不符合该日志级别的接受-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- info.2019-08-21.0.log.gz -->
<fileNamePattern>${LOG_PATH}/info/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<!-- 日志的每个文件,大小最大10MB -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志所有文件的总大小,如果总大小>20GB,它将删除旧文件 -->
<totalSizeCap>20GB</totalSizeCap>
<!-- 保留60天(天:根据fileNamePattern的最小单位为准)的历史纪录 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<!-- 格式化日志输出 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
<!-- 编码 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!--error文件输出-->
<appender name="FILE-ERROR-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果是true,日志被追加到文件结尾,如果是false,清空现存文件,默认是true。-->
<append>true</append>
<file>${LOG_PATH}/error/${LOG_ERROR_FILE}</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- error.2019-08-21.0.log.gz -->
<fileNamePattern>${LOG_PATH}/error/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<!-- 日志的每个文件,大小最大10MB -->
<maxFileSize>10MB</maxFileSize>
<!-- 日志所有文件的总大小,如果总大小>20GB,它将删除旧文件 -->
<totalSizeCap>20GB</totalSizeCap>
<!-- 保留60天的历史纪录 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<!-- 格式化日志输出 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
<!-- 编码 -->
<charset>UTF-8</charset>
</encoder>
</appender>
关于日志输出到文件的配置代码有很多,本文尽量详细地一一说明:
<logger name="com.study.spring.helloDemo" level="WARN" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-INFO-ROLLING"/>
<appender-ref ref="FILE-ERROR-ROLLING"/>
</logger>
上述配置表示:com.study.spring.helloDemo 这个类中的 warn 级别日志将会使用 CONSOLE、FILE-INFO-ROLLING、FILE-ERROR-ROLLING 来打印。logger 有三个属性和一个子标签:
<root level="info">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE-INFO-ROLLING"/>
<appender-ref ref="FILE-ERROR-ROLLING"/>
</root>
上述配置指定项目所有日志输出级别,也是一种 logger ,且只有一个 level 属性。appender-ref 标签用来指定具体的 appender 。
spring-logback.xml 文件是 spring boot 启动项目时进行加载的。但如果单单执行一个 main() 方法,由于没有加载 spring-logback.xml 文件,所以日志不会被加载到文件中,只会输出在控制台。所以首先需要使用代码实现配置文件的加载。完整代码如下:
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import ch.qos.logback.core.util.StatusPrinter;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
/**
* @description: 加载配置文件
*/
public class LogBackConfigLoader {
public static void load (String externalConfigFileLocation) throws IOException, JoranException {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
File externalConfigFile = new File(externalConfigFileLocation);
if(!externalConfigFile.exists()){
throw new IOException("Logback External Config File Parameter does not reference a file that exists");
}else{
if(!externalConfigFile.isFile()){
throw new IOException("Logback External Config File Parameter exists, but does not reference a file");
}else{
if(!externalConfigFile.canRead()){
throw new IOException("Logback External Config File exists and is a file, but cannot be read.");
}else{
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(lc);
lc.reset();
configurator.doConfigure(externalConfigFileLocation);
StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
}
}
}
}
}
我们新建一个类,创建一个 main() 方法,在 main() 方法中添加 spring-logback.xml 文件的加载代码:
LogBackConfigLoader.load(Objects.requireNonNull(LogbackTest.class.getClassLoader().getResource("logback-spring.xml")).getPath());
再结合 slf4j ,可将日志根据 logback-spring.xml 文件的配置进行输出。
测试类,我试着默认情况下也是不加载日志配置的,有两种方法可以解决:
先说第一种:使用 main() 方法那种方式来加载日志配置。
优点:运行测试类,执行速度快。
缺点:配置较第二种方式较复杂,代码量多。
import ch.qos.logback.core.joran.spi.JoranException;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Objects;
/**
* @description: 测试类加载日志配置测试
*/
public class LogbackTest {
private static final Logger logger = LoggerFactory.getLogger(LogbackTest.class);
@Test
public void test(){
try {
LogBackConfigLoader.load(Objects.requireNonNull(LogbackTest.class.getClassLoader().getResource("logback-spring.xml")).getPath());
} catch (IOException | JoranException e) {
e.printStackTrace();
}
logger.info("info123");
logger.warn("warn");
logger.debug("debug");
logger.error("error");
}
}
再说第二种方式:使用 spring boot 注解
优点:配置简单,俩注解完事,代码量少。
缺点:运行测试类,要先类似于启动一遍 spring boot,执行速度慢。
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @description: 测试类加载日志配置测试
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class LogbackTest {
private static final Logger logger = LoggerFactory.getLogger(LogbackTest.class);
@Test
public void test(){
logger.info("info123");
logger.warn("warn");
logger.debug("debug");
logger.error("error");
}
}
logback 作为 spring boot 首选日志框架,其功能十分强大。logback 的配置应该与项目使用场景相挂钩,本文展示的配置只能满足一些通用的需求,权当 logback 的入门教程。如果后续有了新的需求,再进行补充。
本文全部代码已上传至 github :
https://github.com/841809077/spring-boot-study/blob/master/src/main/resources/logback-spring.xml
参考资料: