美文网首页
03.spring-boot与日志

03.spring-boot与日志

作者: 马晓钧 | 来源:发表于2019-01-03 19:50 被阅读0次

spring-boot与日志

使用slf4j

如何让系统中所有的日志都统一到slf4j

  1. 将系统中其他日志框架先排除出去。
  2. 用中间包来替换原有的日志框架。
  3. 我们导入slf4j其他的实现。
spring-boot的日志依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐starter‐logging</artifactId>
</dependency>

总结:

  1. spring-boot底层选用的是slf4j+logback进行日志记录。
  2. spring-boot把其他的日志都替换成了slf4j。
  3. 如果我们要引入其他框架,需要把默认的日志依赖移除掉。
spring-boot的日志使用

导入slf4j的jar和logback的实现jar

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(SpringRunner.class)
@SpringBootTest
public class LoggerApplicationTests {

    @Test
    public void contextLoads() {

        Logger logger = LoggerFactory.getLogger(LoggerApplicationTests.class);
        logger.trace("trace");
        logger.debug("debug");
        logger.info("info");
        logger.warn("warn");
        logger.error("error");

    }

}
日志级别

spring-boot默认日志级别是info

1. trace
2. debug
3. info
4. warn
5. error
日志默认配置修改
日志输出格式: 
    %d:表示日期时间,
    %thread:表示线程名,
    %‐5level:级别从左显示5个字符宽度
    %logger{50}:表示logger名字最长50个字符,否则按照句点分割。 
    %msg:日志消息,
    %n:是换行符
例子:
    %d{yyyy‐MM‐dd HH:mm:ss} [%thread] %-5level %logger- %msg%n

控制台:

//修改默认日志级别,level后面跟着包名
logging.level.com.bafan.springboot.logger=trace
//修改控制台
logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n

指定文件输出:

在实际的项目开发中,我们习惯将日志输出到服务器的某个文件下
  • 需要将日志的配置文件放在类路径下(spring-boot就不使用他默认的配置了)。
  • logback.xml:直接被日志框架识别。
  • logback-spring.xml:日志框架不直接加载日志的配置项,由spring-boot解析日志配置,可以使用spring-boot的高级profile功能。(推荐)。(<springProfile name="dev">可以根据环境来决定功能)

spring-boot识别logback.xml文件

1--LoggingApplicationListener的initialize方法

protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
    (new LoggingSystemProperties(environment)).apply();
    LogFile logFile = LogFile.get(environment);
    if (logFile != null) {
        logFile.applyToSystemProperties();
    }

    this.initializeEarlyLoggingLevel(environment);
    //进入
    this.initializeSystem(environment, this.loggingSystem, logFile);
    this.initializeFinalLoggingLevels(environment, this.loggingSystem);
    this.registerShutdownHookIfNecessary(environment, this.loggingSystem);
}

2--LoggingApplicationListener的initializeSystem方法

private void initializeSystem(ConfigurableEnvironment environment, LoggingSystem system, LogFile logFile) {
    LoggingInitializationContext initializationContext = new LoggingInitializationContext(environment);
    String logConfig = environment.getProperty("logging.config");
    if (this.ignoreLogConfig(logConfig)) {
        //进入
        system.initialize(initializationContext, (String)null, logFile);
    } else {
        try {
            ResourceUtils.getURL(logConfig).openStream().close();
            system.initialize(initializationContext, logConfig, logFile);
        } catch (Exception var7) {
            System.err.println("Logging system failed to initialize using configuration from '" + logConfig + "'");
            var7.printStackTrace(System.err);
            throw new IllegalStateException(var7);
        }
    }

}

3--LogbackLoggingSystem的initialize方法

public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
    LoggerContext loggerContext = this.getLoggerContext();
    if (!this.isAlreadyInitialized(loggerContext)) {
        //调用父类的初始化方法
        super.initialize(initializationContext, configLocation, logFile);
        loggerContext.getTurboFilterList().remove(FILTER);
        this.markAsInitialized(loggerContext);
        if (StringUtils.hasText(System.getProperty("logback.configurationFile"))) {
            this.getLogger(LogbackLoggingSystem.class.getName()).warn("Ignoring 'logback.configurationFile' system property. Please use 'logging.config' instead.");
        }

    }
}

4--AbstractLoggingSystem的initialize方法

public void initialize(LoggingInitializationContext initializationContext, String configLocation, LogFile logFile) {
    if (StringUtils.hasLength(configLocation)) {
        this.initializeWithSpecificConfig(initializationContext, configLocation, logFile);
    } else {
        //进入
        this.initializeWithConventions(initializationContext, logFile);
    }
}

5--AbstractLoggingSystem的initializeWithConventions方法

private void initializeWithConventions(LoggingInitializationContext initializationContext, LogFile logFile) {
    //查找自己的配置(logback.xml)
    String config = this.getSelfInitializationConfig();
    if (config != null && logFile == null) {
        this.reinitialize(initializationContext);    
    } else { //如果没有找到,就去找spring的文件
        if (config == null) {
            //查找spring的配置(logback-spring.xml)
            config = this.getSpringInitializationConfig();
        }

        if (config != null) {
            this.loadConfiguration(initializationContext, config, logFile);
        } else { //如果都没有找到,只使用properties默认的配置
            this.loadDefaults(initializationContext, logFile);
        }
    }
}

6--AbstractLoggingSystem的getSelfInitializationConfig方法,执行结束后到7

protected String getSelfInitializationConfig() {
    //获取spring-boot标准的配置
    return this.findConfig(this.getStandardConfigLocations());
}
protected String[] getStandardConfigLocations() {
    return new String[]{"logback-test.groovy", "logback-test.xml", "logback.groovy", "logback.xml"};
}

7--AbstractLoggingSystem的findConfig方法,执行结束后到5

private String findConfig(String[] locations) {
    String[] var2 = locations;
    int var3 = locations.length;

    //如果能够找到配置文件的位置,则返回配置文件位置,否则返回null
    for(int var4 = 0; var4 < var3; ++var4) {
        String location = var2[var4];
        ClassPathResource resource = new ClassPathResource(location, this.classLoader);
        if (resource.exists()) {
            return "classpath:" + location;
        }
    }

    return null;
}

8--AbstractLoggingSystem的getSpringConfigLocations方法,执行结束后到7

protected String[] getSpringConfigLocations() {   
    String[] locations = this.getStandardConfigLocations();

    for(int i = 0; i < locations.length; ++i) {
        //加上-spring后缀再在跟路径下查找
        String extension = StringUtils.getFilenameExtension(locations[i]);
        locations[i] = locations[i].substring(0, locations[i].length() - extension.length() - 1) + "-spring." + extension;
    }

    return locations;
}

logback常用配置

1--根节点configuration

  • 通常不加任何属性。

2--configuration的子节点

2.1 property
//用来定义变量
<property name="FILE_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %c{35} %M %L - %msg%n"/>
...
<encoder>
    <pattern>${FILE_PATTERN}</pattern>
</encoder>
2.2 logger
  • name:用来指定受此logger约束的某一个包或者具体的某一个类。
  • level:用来打印日志级别。(root<append<logger)
  • additivity:是否向上级传递打印信息,默认是true,项目中都用false
<logger name="com.mogujie.raptor" level="@root.log.level@" additivity="false">
    <appender-ref ref="RAPTOR_FILE"/>
</logger>
2.3 root
  • 也属于logger标签,只有一个属性,定义日志级别,默认是全路径。
<root level="INFO">
    <appender-ref ref="STDOUT" />
    <appender-ref ref="FILE" />
</root>

3--appender和它的子节点

  • appender是configuration的子节点。
  • name:指定appender名称,class指定appender的全限名。
3.1 ConsoleAppender
  • 控制台日志
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
    </encoder>
</appender>
3.2 RollingFileAppender
滚动日志文件:先将日志记录到指定文件,当符合某个条件的时候,将日志记录到 其它文件。FileAppender没有滚动功能,要么追加要么覆盖,项目中几乎不用。
  • file:写入文件的名字。
  • append:默认是true、追加;false是覆盖。
  • encoder:对记录事件进行格式化。一是把日志信息转成字节数组,二是把字节数组写入输出流。
  • rollingPolicy:发生滚动时,涉及文件移动和重命名。
rollingPolicy:
  • TimeBasedRollingPolicy:最常用的滚动方式,根据时间制定滚动策略,既负责滚动,也负责触发滚动。
  1. fileNamePattern:包含文件名及“%d”转换符。
  2. maxHistory:保留最大时间,根据fileNamePattern的时间决定单位是年月日。
  3. timeBasedFileNamingAndTriggeringPolicy:当文件大小超过多少时触发滚动,里面配置maxFileSize,例如500MB。
<appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
        <pattern>${FILE_PATTERN}</pattern>
    </encoder>
    <Encoding>UTF-8</Encoding>
    <file>${CATALINA_APPLOG}/finance_mall_error.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>${CATALINA_APPLOG}/finance_mall_error_%d{yyyy_MM_dd}-%i.log</fileNamePattern>
        <MaxHistory>10</MaxHistory>
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>500MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
</appender>
4. filter
属于appender下的标签,一般用于日志级别过滤
  • level:日志级别
  • onMatch:如果匹配上,接受(ACCEPT)
  • onMismatch:如果没有匹配上,拒绝(DENY)
<filter class="ch.qos.logback.classic.filter.LevelFilter"> 
  <level>INFO</level> 
  <onMatch>ACCEPT</onMatch> 
  <onMismatch>DENY</onMismatch> 
</filter> 

相关文章

网友评论

      本文标题:03.spring-boot与日志

      本文链接:https://www.haomeiwen.com/subject/zzmqrqtx.html