Logback日志框架

日志的作用:用来追踪和记录程序运行中的信息
常见的日志框架:logback、log4j、log4j2、jul

简介

logback是在log4j的基础上重新开发的一套日志框架,完全实现了slf4j(日志门面)的接口API
共有三个模块:

  • logback-core:核心组件
  • logback-classic:原生实现了slf4j API
  • logback-access:与tomcat、jetty等servlet容器集成,提供HTTP访问日志功能

集成

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.3.7</version>
</dependency>

测试

public class LogbackTest {
    //创建记录器
    static Logger logger = LoggerFactory.getLogger(LogbackTest.class);
    //日志级别(从低到高):trace < debug < info < warn < error
    public static void main(String[] args) {
        //根记录器,默认不会打印这个级别的日志
        logger.trace("test trace");
        //根记录器默认日志打印级别
        logger.debug("test debug");
        logger.info("test info");
        logger.warn("test warn");
        logger.error("test error");
    }
}

记录器(logger)

控制要输出哪些日志记录语句,对日志级别进行限制

创建记录器

final static Logger logger = LoggerFactory.getLogger("记录器名称");
记录器存在父子关系,是通过记录器的名称来确定的

结构

  • 1、执行Logger logger = LoggerFactory.getLogger("com.tzcxyh.logback.LogbackTest");时,记录器如下:

  • 2、然后执行Logger logger = LoggerFactory.getLogger("com.tzcxyh.logback.LogbackTest2");时,记录器如下:

第一次创建时,会创建各级的Logger记录器,之后创建,如果父级已经存在,不会重复创建

属性

  • name:记录器的名称,会根据名称,创建具有父子关系的记录器
  • **level(可选):**记录器级别,允许的级别(从低到高:trace < debug < info < warn < error)
  • additivity(可选): 是否允许叠加打印日志,true(默认) / false

设置记录器级别测试

public class LoggerCodeTest {

    @Test
    public void testSetLevel(){
        //需要强转为 ch.qos.logback.classic.Logger 
        Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback");
        System.out.println("=====================输出设置前级别============");
        System.out.println("设置前日志级别: " + logger.getEffectiveLevel());
        //设置为Info级别
        logger.setLevel(Level.INFO);
        System.out.println("=====================输出设置后级别============");
        System.out.println("设置后日志级别: " + logger.getEffectiveLevel());
        //测试日志输出--只会打印大于设置级别的日志
        System.out.println("=====================设置后日志输出情况============");
        logger.trace("test trace");
        logger.debug("test debug");
        logger.info("test info");
        logger.warn("test warn");
        logger.error("test error");
    }
}

setLevel(Level.INFO)效果和在xml中配置一致

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="com.tzcxyh.logback.LoggerCodeTest" level="INFO">
        <appender-ref ref="CONSOLE"/>
    </logger>
</configuration>

image.png

日志可加性设置测试

additivity默认为true,即向上传递

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
        </encoder>
    </appender>
    
    <logger name="com.tzcxyh.logback.LoggerCodeTest">
        <appender-ref ref="CONSOLE"/>
    </logger>

    <logger name="com.tzcxyh.logback">
        <appender-ref ref="CONSOLE"/>
    </logger>

    <logger name="com.tzcxyh">
        <appender-ref ref="CONSOLE"/>
    </logger>
</configuration>
public class LoggerCodeTest {
	@Test
	public void testAdditivity(){
		Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback.LoggerCodeTest");
		System.out.println("=====================设置前日志输出情况============");
		logger.debug("test debug ");
		System.out.println("=====================设置后日志输出情况============");
		logger.setAdditive(false);
		logger.debug("test debug");
	}
}

image.png

附加器(appender)

记录器(logger)会将输出日志的任务交给附加器来完成,不同的附加器会将日志输出到不同的地方。如:控制台、文件、网络

pattern标签

由文字文本+转换说明符的格式来控制表达式的组成。
转换说明符 = %+(格式转换符、转换字、大括号之间的可选参数)

转换字 描述 例子
logger{length} 输出记录器的名称 %logger{5}
class{length} 调用者全类名 %class
line 行号 %line
date{}/date{} 时间 %date{yyyy-MM-dd}
level 日志级别 %level
thread 日志所在线程 %thread
msg 日志信息 %msg

控制台附加器

ch.qos.logback.core.ConsoleAppender,日志输出到控制台

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <!--设置日志的附加器-->
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <!--设置日志格式-->
      <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
    </encoder>
  </appender>
  <!--记录器,将日志传递到附加器中-->
  <logger name="com.tzcxyh.logback.LoggerCodeTest">
    <appender-ref ref="CONSOLE"/>
  </logger>
</configuration>

文件附加器

ch.qos.logback.core.FileAppender,日志输出到文件中

  • : 设置文件输出位置和文件名称
  • :设置日志是否追加到文件中。true(追加)/false(覆盖)
<?xml version="1.0" encoding="UTF-8"?>
<configuration  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="logback.xsd">

  <appender name="FILE-LOG" class="ch.qos.logback.core.FileAppender">
    <encoder>
      <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
    </encoder>
    <!--指定文件输出位置和名称-->
    <file>./file-log/logback</file>
    <!--是否追加:true 追加,false 覆盖-->
    <append>false</append>
  </appender>
  <!--配置三个logger-->
  <logger name="com.tzcxyh.logback.LoggerCodeTest">
    <appender-ref ref="FILE-LOG"/>
  </logger>
</configuration>
public class LoggerCodeTest {
	@Test
	public void testFileAppender(){
		Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback.LoggerCodeTest");
		logger.debug("test debug ");
	}
}

滚动文件附加器

ch.qos.logback.core.rolling.RollingFileAppender,日志滚动输出到文件中。相比于文件附加器,避免了日志文件过大

  • :设置滚动策略,可以设置基于时间(ch.qos.logback.core.rolling.TimeBasedRollingPolicy)/基于大小和时间(ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy)
  • :配置文件格式, %d{归档条件},文件会按归档条件切割
  • :按规范条件切割日志后,最多保留多少个日志文件
  • :所有日志文件占用最大内存容量

基于时间的滚动策略

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
      <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
    </encoder>
    <!--指定文件输出位置和名称-->
    <file>./file-log/logback.log</file>
    <append>true</append>
    <!--指定滚动策略-->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!--配置文件名称 %d{归档条件}-->
      <fileNamePattern>./file-log/%d{HH-mm-ss}.log</fileNamePattern>
      <!--最多保留多少个日志文件-->
      <maxHistory>30</maxHistory>
      <!--占用最大内存容量-->
      <totalSizeCap>1MB</totalSizeCap>
    </rollingPolicy>
  </appender>
  <!--配置logger-->
  <logger name="com.tzcxyh.logback.LoggerCodeTest">
    <appender-ref ref="FILE-LOG"/>
  </logger>
</configuration>
public class LoggerCodeTest {
	@Test
	public void testRollingFileAppender() throws InterruptedException {
		Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback.LoggerCodeTest");
		int i = 0;
		while (true){
			Thread.sleep(500);
			logger.debug("test debug " + i++);
		}
	}
}

image.png

基于大小和时间的滚动策略

  • : 相比与按时间的滚动策略,需要多配置一个%i,在同一个归档条件中,按<maxFileSize>近一步切割日志是,i会递增
  • : 每个日志文件最大内存
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
      <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
    </encoder>
    <!--指定文件输出位置和名称-->
    <file>./file-log/logback.log</file>
    <append>true</append>
    <!--指定滚动策略-->
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!--配置文件名称 %d{归档条件}  %i 同一个归档时间内,如果有多个文件,i累加-->
      <fileNamePattern>./file-log/%d{HH-mm}.%i.log</fileNamePattern>
      <!--最多保留多少个日志文件-->
      <maxHistory>30</maxHistory>
      <!--每个日志文件最大内存,与%d的配置看哪个先满足-->
      <maxFileSize>2KB</maxFileSize>
      <!--占用最大内存容量-->
      <totalSizeCap>1MB</totalSizeCap>
    </rollingPolicy>
  </appender>
  <!--配置三个logger-->
  <logger name="com.tzcxyh.logback.LoggerCodeTest">
    <appender-ref ref="FILE-LOG"/>
  </logger>
</configuration>

image.png

过滤器(filter)

过滤器是附加器中的一个组件,用于决定附加器是否输出日志。可以配置一个或者多个。
枚举值:DENY(不输出)、ACCEPT(输出)、NEUTRAL(中立,由下一个过滤器觉得)

级别过滤器

ch.qos.logback.classic.filter.LevelFilter,判断日志级别是否与配置级别相等。
如果当前日志级别 = 配置级别,返回<onMatch>配置的值;否则返回<onMismatch>配置的值
image.png

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
        </encoder>
        <!--配置级别过滤器-->
        <filter class = "ch.qos.logback.classic.filter.LevelFilter">
            <!--配置INFO级别-->
            <level>INFO</level>
            <!--onMatch ACCEPT(输出) -->
            <onMatch>ACCEPT</onMatch>
            <!--onMismatch DENY(不输出) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--配置三个logger-->
    <logger name="com.tzcxyh.logback.LoggerCodeTest">
        <appender-ref ref="CONSOLE"/>
    </logger>
</configuration>
public class LoggerCodeTest {
    @Test
    public void testLevelFilter(){
        Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback.LoggerCodeTest");
        logger.trace("test trace");
        logger.debug("test debug");
        logger.info("test info");
        logger.warn("test warn");
        logger.error("test error");
    }
}

image.png

阈值过滤器

ch.qos.logback.classic.filter.ThresholdFilter,判断日志级别是否大于等于配置级别。
如果当前日志级别 >= 配置级别,返回NEUTRAL;否则返回DENY
image.png

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%date{hh:mm:ss.SSS} %thread %level %class -- %msg%n</pattern>
    </encoder>
    <!--配置级别过滤器-->
    <filter class = "ch.qos.logback.classic.filter.ThresholdFilter">
      <!--配置INFO级别-->
      <level>INFO</level>
    </filter>
  </appender>
  <!--配置三个logger-->
  <logger name="com.tzcxyh.logback.LoggerCodeTest">
    <appender-ref ref="CONSOLE"/>
  </logger>
</configuration>
public class LoggerCodeTest {
    @Test
    public void testThresholdFilter(){
        Logger logger = (Logger) LoggerFactory.getLogger("com.tzcxyh.logback.LoggerCodeTest");
        logger.trace("test trace");
        logger.debug("test debug");
        logger.info("test info");
        logger.warn("test warn");
        logger.error("test error");
    }
}

image.png

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>