Java slf4j 日志框架
slf4j 全称 Simple Logging Facade for Java, 是日志框架的一种抽象, 那么也就是说 slf4j 是不能单独使用的必须要有其他实现日志框架来配合使用
slf4j只是一个日志标准,并不是日志系统的具体实现。理解这句话非常重要,slf4j只做两件事情:
- 提供日志接口
- 提供获取具体日志对象的方法
slf4j 门面依赖
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
implementation("org.slf4j:slf4j-api:2.0.9")
implementation("org.slf4j:slf4j-api:2.0.17")
注意一点, 因具体实现不同引的包也不同, 配置方式也不同!!
log4j 实现
slf4j与log4j整合导入的jar包为:
- slf4j-api.jar
- slf4j-log4j12.jar //读取 log4j.xml 或 log4j.properties
- log4j.jar
不推荐
log4j2 实现
slf4j与log4j2整合导入的jar包为:
- log4j-slf4j-impl.jar
- log4j-api.jar
- log4j-core.jar
<dependencies>
<!-- SLF4J API -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<!-- SLF4J到Log4j2的绑定 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
<!-- Log4j2核心 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>logback 实现
slf4j与logback整合导入的jar包为:
- slf4j-api.jar
- logback-core.jar //读取 logback.xml
- logback-classic.jar
maven 依赖
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>implementation("ch.qos.logback:logback-classic:1.5.16")
implementation("ch.qos.logback:logback-core:1.5.16")
logback 自用 java 模版
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志格式 -->
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %logger{50}::%M-%line:%msg%n" />
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>${LOG_PATTERN}</Pattern>
<charset>utf8</charset>
</encoder>
</appender>
<appender name="INFO_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 按天来回滚,如果需要按小时来回滚,则设置为{yyyy-MM-dd_HH} -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 回滚文件名 -->
<fileNamePattern>./logs/info-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为maxHistory 天,maxHistory天之前的都将被清理掉 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>${LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="WARN_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/warn.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 按天来回滚,如果需要按小时来回滚,则设置为{yyyy-MM-dd_HH} -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 回滚文件名 -->
<fileNamePattern>./logs/warn-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为maxHistory 天,maxHistory天之前的都将被清理掉 -->
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>${LOG_PATTERN}</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<!-- 按天来回滚,如果需要按小时来回滚,则设置为{yyyy-MM-dd_HH} -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/error-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为maxHistory天,maxHistory天之前的都将被清理掉 -->
<maxHistory>120</maxHistory>
</rollingPolicy>
<!-- 日志输出格式 -->
<encoder>
<Pattern>${LOG_PATTERN}</Pattern>
</encoder>
</appender>
<!-- 异步输出,异步的log片段必须在同步段后面,否则不起作用 -->
<appender name="ASYNC_INFO_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>10000</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="INFO_FILE" />
</appender>
<appender name="ASYNC_WARN_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>10000</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="WARN_FILE" />
</appender>
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>10000</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="ERROR_FILE" />
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_INFO_FILE" />
<appender-ref ref="ASYNC_WARN_FILE" />
<appender-ref ref="ASYNC_ERROR_FILE" />
</root>
</configuration>logback 自用 spring-boot模版
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- logback -->
<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})::%M-%L%clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- Console 输出设置 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
<appender name="INFO_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 按天来回滚, 如果需要按小时来回滚, 则设置为{yyyy-MM-dd_HH} -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 回滚文件名 -->
<fileNamePattern>./logs/info-%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 如果按天来回滚, 则最大保存时间为maxHistory 天, maxHistory天之前的都将被清理掉 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<!-- 日志输出格式 -->
<encoder>
<Pattern>%d -%-4r [%t] %-5p %c::%M-%L %m%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="WARN_FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/warn.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/warn-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>%d -%-4r [%t] %-5p %c::%M-%L %m%n</Pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./logs/error-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>120</maxHistory>
</rollingPolicy>
<encoder>
<Pattern>%d -%-4r [%t] %-5p %c::%M-%L %m%n</Pattern>
</encoder>
</appender>
<!-- 异步输出, 异步的log片段必须在同步段后面, 否则不起作用 -->
<appender name="ASYNC_INFO_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT, DEBUG, INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>10000</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="INFO_FILE" />
</appender>
<appender name="ASYNC_WARN_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>10000</queueSize>
<appender-ref ref="WARN_FILE" />
</appender>
<appender name="ASYNC_ERROR_FILE" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>10000</queueSize>
<appender-ref ref="ERROR_FILE" />
</appender>
<root level="INFO">
<!-- 用异步输出的 appender-->
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_INFO_FILE" />
<appender-ref ref="ASYNC_WARN_FILE" />
<appender-ref ref="ASYNC_ERROR_FILE" />
</root>
<!--监控sql日志输出 -->
<logger name="jdbc.sqlonly" level="INFO" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="jdbc.resultset" level="ERROR" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="jdbc.resultsettable" level="OFF" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="jdbc.connection" level="OFF" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="jdbc.sqltiming" level="OFF" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
<logger name="jdbc.audit" level="OFF" additivity="false">
<appender-ref ref="CONSOLE" />
</logger>
</configuration>for android
- In
app/build.gradle, add the following dependencies:
dependencies {
compile 'org.slf4j:slf4j-api:1.7.25'
compile 'com.github.tony19:logback-android:2.0.0'
}
- Create
app/src/main/assets/logback.xml
…
自定义日志 Appender
logback的自定义,都是基于一个基类appender来实现。本身logback提供了AppenderBase和UnsynchronizedAppenderBase两个抽象类(同步和非同步)
start方法:初始时调用。故在编写如数据库入库,连接缓存或者mq时,可以在这个方法里面进行初始化操作。 stop:当停止时,调用。可做些资源释放操作。
SpringBoot | 第二十五章:日志管理之自定义Appender
package org.yang.agenta.log;
import ch.qos.logback.core.AppenderBase;
public class MyLogAppender extends AppenderBase {
@Override
protected void append(Object eventObject) {
System.out.println("自定义输出=== " + eventObject);
}
}<!-- 自定义输出 -->
<property name="CUST_LOG_PATTERN" value="%d -%-4r [%t] %-5p %c-%L: %m%n" />
<!-- CUST 输出设置 -->
<appender name="CUST" class="org.yang.agenta.log.MyLogAppender">
<encoder>
<pattern>${CUST_LOG_PATTERN}</pattern>
<charset>utf8</charset>
</encoder>
</appender>
Junit
注解
@Test :表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
@ParameterizedTest :表示方法是参数化测试
@RepeatedTest :表示方法可重复执行,下方会有详细介绍
@DisplayName :为测试类或者测试方法设置展示名称
@BeforeEach :表示在每个单元测试之前执行
@AfterEach :表示在每个单元测试之后执行
@BeforeAll :表示在所有单元测试之前执行(需要将测试方法设置为statis)
@AfterAll :表示在所有单元测试之后执行(需要将测试方法设置为statis)
@Tag :表示单元测试类别,类似于JUnit4中的@Categories
@Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
@Timeout :表示测试方法运行如果超过了指定时间将会返回错误
@ExtendWith :为测试类或测试方法提供扩展类引用