SpringBoot配置logback.xml,控制台设置彩色字体,按日志级别划分log文件

欢迎阅读另一篇关于SpringBoot中日志的文章 SpringBoot动态修改日志级别
本文基于SpringBoot2.6讲解
本文内容:

  1. 按照日志级别输出到不同日志文件
  2. 控制台日志设置和SpringBoot同风格彩色字体样式
  3. 指定该包下的日志都打印在customAppender中指定的文件路径
  4. 启动后不变的日志打印到单独的包,例如环境变量打印到environment.log中
  5. 按照springboot环境配置日志

初始化一个SpringBoot后启动项目,控制台会带有彩色日志样式.但是当我们配置了自己的logback-spring.xml日志文件时,样式可能就不存在了,console控制台变成了黑白屏。
其实彩色日志样式是SpringBoot自己做了特殊处理,实现了Logback的conversionRule,源码参见:org.springframework.boot.logging.logback.DefaultLogbackConfiguration
我们可以直接在logback-spring.xml中使用SpringBoot实现的conversionRule,让console日志变成彩屏。

logback-spring.xml中如下几个参数

CONSOLE_LOG_PATTERN
FILE_LOG_PATTERN
LOG_DATEFORMAT_PATTERN
LOG_LEVEL_PATTERN
LOG_EXCEPTION_CONVERSION_WORD
LOG_PATH
CONSOLE_LOG_CHARSET
FILE_LOG_CHARSET

对应SpringBoot的几个配置

logging.pattern.console=
logging.pattern.file=
logging.pattern.level=
logging.pattern.dateformat=
logging.exception-conversion-word=
logging.file.path=logs
logging.charset.console=UTF-8
logging.charset.file=UTF-8

logback-spring.xml放到resources目录即可被SpringBoot识别


<configuration debug="false">

    
    
    <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="LOG_HOME" value="${LOG_PATH:-logs}"/>
    <property name="FILE_LOG_CHARSET" value="${FILE_LOG_CHARSET:-UTF-8}"/>
    <property name="CONSOLE_LOG_CHARSET" value="${CONSOLE_LOG_CHARSET:-UTF-8}"/>
    
    <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN:-%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } [%t] %-40.40logger{39} %-4line : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>


    
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <pattern>pattern>
            <charset>${CONSOLE_LOG_CHARSET}charset>
        encoder>
        
        
        
        
        
    appender>

    
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/debug.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME}/debug.%d{yyyy-MM-dd}.%i.logFileNamePattern>
            <MaxHistory>5MaxHistory>
            <maxFileSize>100MBmaxFileSize>
        rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}pattern>
            <charset>${FILE_LOG_CHARSET}charset>
        encoder>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUGlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/info.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.%i.logFileNamePattern>
            <MaxHistory>5MaxHistory>
            <maxFileSize>100MBmaxFileSize>
        rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}pattern>
            <charset>${FILE_LOG_CHARSET}charset>
        encoder>
        
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    <appender name="WARN_ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/warn-error.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME}/warn-error.%d{yyyy-MM-dd}.%i.logFileNamePattern>
            <MaxHistory>5MaxHistory>
            <maxFileSize>100MBmaxFileSize>
        rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            
            <pattern>${FILE_LOG_PATTERN}pattern>
            <charset>${FILE_LOG_CHARSET}charset>
        encoder>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARNlevel>
            
            
            <onMatch>ACCEPTonMatch>
            <onMismatch>NEUTRALonMismatch>
        filter>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            
            <level>ERRORlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>

    
    <root level="INFO">
        <appender-ref ref="Console"/>
        
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_ERROR_FILE"/>
    root>


    <appender name="environmentAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/environment.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME}/environment.%d{yyyy-MM-dd}.%i.logFileNamePattern>
            <MaxHistory>5MaxHistory>
            <maxFileSize>100MBmaxFileSize>
        rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>ACCEPTonMismatch>
        filter>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${PID:- } [%t] %-10.40logger{39} : %m%n%wExpattern>
            <charset>${FILE_LOG_CHARSET}charset>
        encoder>
    appender>

    
    <logger name="environment" level="INFO" additivity="false">
        <appender-ref ref="environmentAppender"/>
    logger>

    <appender name="customAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/custom.logfile>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <FileNamePattern>${LOG_HOME}/custom.%d{yyyy-MM-dd}.%i.logFileNamePattern>
            <MaxHistory>5MaxHistory>
            <maxFileSize>100MBmaxFileSize>
        rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>ACCEPTonMismatch>
        filter>
        <encoder>
            <pattern>${FILE_LOG_PATTERN}pattern>
            <charset>${FILE_LOG_CHARSET}charset>
        encoder>
    appender>

    
    <logger name="com.bruce.kafka">
        <appender-ref ref="customAppender"/>
    logger>

configuration>

environment 日志配置的使用
通过LoggerFactory获取名称为environment的Logger对象即可

@SpringBootApplication
public class KafkaProducerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(KafkaProducerApplication.class, args);

        Logger envLogger = LoggerFactory.getLogger("environment");

        ConfigurableEnvironment environment = context.getEnvironment();
        MutablePropertySources propertySources = environment.getPropertySources();

        for (PropertySource<?> propertySource : propertySources) {
            envLogger.info(propertySource.getName());
        }

        for (PropertySource<?> propertySource : propertySources) {
            if (propertySource instanceof EnumerablePropertySource) {
                EnumerablePropertySource<?> enumerablePropertySource = (EnumerablePropertySource<?>) propertySource;
                String[] propertyNames = enumerablePropertySource.getPropertyNames();
                for (String propertyName : propertyNames) {
                    envLogger.info("[{}] {} = {}", propertySource.getName(), propertyName, enumerablePropertySource.getProperty(propertyName));
                }
            }
        }

    }
}

SpringBoot配置logback.xml,控制台设置彩色字体,按日志级别划分log文件_第1张图片
如果想让environment中的日志在控制台展示,但不输入到info.log, warn-error.log中,可以将additivity设置为true,并在INFO, WARN-ERROR appender中使用自定义的Filter,过滤掉LoggerName为environment的日志. 参见: ch.qos.logback.classic.filter.LevelFilter

/**
 * Created by bruce on 2021/11/30 20:05
 */
public class LevelAndNameFilter extends AbstractMatcherFilter<ILoggingEvent> {

    Level level;

    @Override
    public FilterReply decide(ILoggingEvent event) {
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }

        if (event.getLoggerName().equals("environment")){
            return onMismatch;
        }

        if (event.getLevel().equals(level)) {
            return onMatch;
        } else {
            return onMismatch;
        }
    }

    public void setLevel(Level level) {
        this.level = level;
    }

    public void start() {
        if (this.level != null) {
            super.start();
        }
    }
}

按照SpringBoot环境配置日志

  
 <springProfile name="default">
      <root level="debug">
          <appender-ref ref="Console"/>
          <appender-ref ref="DEBUG_FILE"/>
          <appender-ref ref="INFO_FILE"/>
          <appender-ref ref="WARN_ERROR_FILE"/>
      root>
  springProfile>

  <springProfile name="fat | uat">
      <root level="info">
          <appender-ref ref="DEBUG_FILE"/>
          <appender-ref ref="INFO_FILE"/>
          <appender-ref ref="WARN_ERROR_FILE"/>
      root>
  springProfile>

  <springProfile name="pro">
      <root level="warn">
          <appender-ref ref="WARN_ERROR_FILE"/>
      root>
  springProfile>

当应用不以SpringBoot方式启动,仅仅作为一个普通main时,发现控制台彩色日志没有了,此时需要手动调用

AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
public static void main(String[] args) {
     System.setProperty("java.awt.headless", "true");
     AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);

    //SpringApplication.run(NettyHttp2Application.class, args);

    Http2Server http2Server = new Http2Server();
    http2Server.start(8443);
}

最少依赖为

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-bootartifactId>
    <exclusions>
        <exclusion>
            <groupId>*groupId>
            <artifactId>*artifactId>
        exclusion>
    exclusions>
dependency>


<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-coreartifactId>
    <exclusions>
        <exclusion>
            <groupId>*groupId>
            <artifactId>*artifactId>
        exclusion>
    exclusions>
dependency>

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-loggingartifactId>
dependency>

你可能感兴趣的:(spring,boot,logback)