1、简单介绍
Logback 是由 Log4j 创始人设计的又一个开源日志组件。作为流行的 Log4j 项目的继承者,在 log4j 1.x 停止的地方接手。其架构非常通用,可以在不同的情况下应用。
主要分为三个模块:
logback-core :其它两个模块的基础模块
logback-classic :它是log4j的一个改良版本,同时它完整实现了slf4j API因此您可以轻松地在logback和其他日志框架(如log4j或java.util.logging)之间来回切换。
logback-access :访问模块与Servlet容器集成提供通过Http来访问日志的功能
1.1、组件介绍
Logback 的三个组件: Logger、
Appender
和 Layout
。
这三种类型的组件协同工作,使开发人员能够根据消息类型和级别记录消息,并在运行时控制这些消息的格式和报告位置。
1.2、Logger记录器
Loggers(记录器)控制日志的输出级别,规则是:只输出级别不低于设定级别的日志信息。以及引用 Appenders(输出器)。
1.3、Appender输出器
Appender(输出器)将日志记录请求打印到多个目的地,如控制台、文件、数据库等等。有一个根记录器位于记录器层次结构的顶部,它从一开始就是每个层次结构的一部分。Loggers(记录器)之间有继承关系。
1.4、Layout格式器
Layout(格式器)将事件转换成字符串,将日志信息格式化并输出。在 Logback 中 Layout 对象被封装在 encoder 中。
常用转换:
2、日志级别
ALL < TRACE < DEBUG < INFO < WARN < ERROR <FATAL <OFF
ALL:最低等级的,用于打开所有日志记录 TRACE:很低的日志级别,一般不会使用 DEBUG(默认):指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息 INFO:消息在粗粒度级别上突出强调应用程序的运行过程。打印一些感兴趣的或者重要的信息,这个可以用于生产环境中输出程序运行的一些重要信息,但是不能滥用,避免打印过多的日志 WARN:表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给出的一些提示 ERROR:指出虽然发生错误事件,但仍然不影响系统的继续运行。打印错误和异常信息,如果不想输出太多的日志,可以使用这个级别 FATAL:指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别可以直接停止程序了 OFF:最高等级的,用于关闭所有日志记录。
3、入门案列
导入依赖:
<dependencies>
<!--导入slf4j日志门面-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- 导入logback依赖 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 导入单元测试依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
代码:
@Test
public void test01(){
Logger logger = LoggerFactory.getLogger(LogBackTest.class);
logger.trace("trace追踪信息");
logger.debug("debug详细信息"); // 默认级别
logger.info("info关键信息");
logger.warn("warn警告信息");
logger.error("error错误信息");
}
运行结果:
18:11:26.606 [main] DEBUG com.xb.LogBackTest - debug详细信息
18:11:26.611 [main] INFO com.xb.LogBackTest - info关键信息
18:11:26.611 [main] WARN com.xb.LogBackTest - warn警告信息
18:11:26.611 [main] ERROR com.xb.LogBackTest - error错误信息
4、配置文件
Logback 提供了 3 种配置文件: logback.groovy ,logback-test.xml ,logback.xml ,若都不存在则采用默认配置。
总的来说就是围绕三个组件进行配置的
4.1控制台输出
创建配置文件: logback.xml.
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!-- 配置控制台输出器-->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置日志字体颜色,默认黑色(System.out),红色(System.err) -->
<target>System.err</target>
<!-- 配置日志输出格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 引用自定义日志输出格式 -->
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 -->
<appender-ref ref="consoleAppender"/>
</root>
</configuration>
代码:
@Test
public void test01(){
Logger logger = LoggerFactory.getLogger(LogBackTest.class);
logger.trace("trace追踪信息");
logger.debug("debug详细信息"); // 默认级别
logger.info("info关键信息");
logger.warn("warn警告信息");
logger.error("error错误信息");
}
运行结果:默认debug,但xml设置了all
[TRACE] 2023-06-06 18:32:58.857 [main] [com.xb.LogBackTest#test01-19] trace追踪信息
[DEBUG] 2023-06-06 18:32:58.859 [main] [com.xb.LogBackTest#test01-20] debug详细信息
[INFO ] 2023-06-06 18:32:58.859 [main] [com.xb.LogBackTest#test01-21] info关键信息
[WARN ] 2023-06-06 18:32:58.860 [main] [com.xb.LogBackTest#test01-22] warn警告信息
[ERROR] 2023-06-06 18:32:58.860 [main] [com.xb.LogBackTest#test01-23] error错误信息
4.2保存日志
保存到log文件当中,配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 配置自定义日志输出格式 -->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!-- 配置日志输出目录 -->
<property name="logDir" value="../logDir"/>
<!-- 配置文件输出器 -->
<appender name="fileAppender" class="ch.qos.logback.core.FileAppender">
<!-- 配置日志输出文件 -->
<file>${logDir}/logback.log</file>
<!-- 配置日志输出格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 引用自定义日志输出格式 -->
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用文件输出器-->
<appender-ref ref="fileAppender"/>
</root>
</configuration>
保存到HTML文件当中,配置文件:日志内容不多常用html方式
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!-- 配置文件输出位置-->
<property name="logDir" value="../logDir"></property>
<!-- 配置HTml文件输出-->
<appender name="htmlAppender" class="ch.qos.logback.core.FileAppender">
<!--配置html文件输出位置-->
<file>${logDir}/loaback.html</file>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.classic.html.HTMLLayout">
<pattern>${pattern}</pattern>
</layout>
</encoder>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 -->
<appender-ref ref="htmlAppender"/>
</root>
</configuration>
日志文件拆分:当日志文件内容过多的时候(大小)
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!-- 配置文件输出位置-->
<property name="logDir" value="../logDir"></property>
<!-- 配置文件的appender 可拆分归档文件-->
<appender name="roll" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--配置日志文件存储位置-->
<file>${logDir}/roll_logback.log</file>
<!-- 日志输入格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<!-- 指定拆分规则-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--按照时间和压缩格式声明文件名,压缩格式gz-->
<fileNamePattern>${logDir}/roll.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
<!-- 按照文件大小进行拆分-->
<maxFileSize>1KB</maxFileSize>
</rollingPolicy>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 可以配置多个appender做多向输出-->
<appender-ref ref="roll"/>
</root>
</configuration>
5、日志过滤
过滤器写在 Appender 标签内,可以配置一个或多个,按照先后顺序执行。过滤器会对每个级别的日志设置枚举值,表示对日志的处理方式。
级别过滤器:
level:设置日志级别
onMatch:对符合过滤级别的日志操作
onMismatch:对不符合过滤级别的日志操作
过滤器枚举值:
DENY:当前过滤器直接拒绝日志输出,不再经过后续的过滤器
NEUTRAL:有序列表里的下个过滤器过接着处理日志;(该级别既不处理,也不抛弃,相当于没有任何处理,日志会被保存下来并在本appender被执行)
ACCEPT:当前过滤器直接进行日志输出,不再经过后续的过滤器。
5.1 级别过滤:
LevelFilter: 级别过滤器,对特定某个级别的日志进行过滤。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!--配置过滤器-->
<appender name="filterAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置日志字体颜色,默认黑色(System.out),红色(System.err) -->
<target>System.err</target>
<!--配置输出格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--设置过滤级别-->
<level>ERROR</level>
<!-- 打印符合过滤级别的-->
<onMatch>ACCEPT</onMatch>
<!-- 屏蔽不符合过滤级别的-->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 可以配置多个appender做多向输出-->
<appender-ref ref="filterAppender"/>
</root>
</configuration>
运行结果:
[ERROR] 2023-06-06 21:43:22.882 [main] [com.xb.LogBackTest#test01-23] error错误信息
结果:
5.2、临界值过滤器
ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。
它没有过多的参数,只有默认配置。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志返回DENY。
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!--配置过滤器-->
<appender name="filterAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置日志字体颜色,默认黑色(System.out),红色(System.err) -->
<target>System.err</target>
<!--配置输出格式-->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<!--设置过滤级别-->
<level>INFO</level>
</filter>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 可以配置多个appender做多向输出-->
<appender-ref ref="filterAppender"/>
</root>
</configuration>
运行结果:
[INFO ] 2023-06-06 21:56:10.373 [main] [com.xb.LogBackTest#test01-21] info关键信息
[WARN ] 2023-06-06 21:56:10.375 [main] [com.xb.LogBackTest#test01-22] warn警告信息
[ERROR] 2023-06-06 21:56:10.376 [main] [com.xb.LogBackTest#test01-23] error错误信息
结果:最终,info及大于info级别的日志打印的控制台,info以下,debug及debug以上的日志,被抛弃掉。
6、异步日志
同步执行会发生的问题:
1.只要是在记录日志,那么系统本身的功能就处于一种停滞的状态。
2.当日志记录完毕后,才会执行系统本身业务代码。
3.如果日志的记录量很大,那对于系统本身业务代码的执行效率会降低。
所以 Logback 为此提供了异步日志功能。原理就是系统为日志操作单独分配一条线程,原本执行当前方法的主线程会继续向下执行,两条线程争夺 CPU 使用权。
配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!-- 配置自定义日志格式输出-->
<property name="pattern" value="[%-5le] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%c#%M-%L] %m%n"></property>
<!-- 配置控制台输出器-->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置日志字体颜色,默认黑色(System.out),红色(System.err) -->
<target>System.err</target>
<!-- 配置日志输出格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 引用自定义日志输出格式 -->
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!--配置异步-->
<appender name="asyncAppender" class="ch.qos.logback.classic.AsyncAppender">
<!--引用控制台输出-->
<appender-ref ref="filterAppender"/>
</appender>
<!-- 配置记录器 -->
<root level="ALL">
<!-- 引用控制台输出器 可以配置多个appender做多向输出-->
<appender-ref ref="asyncAppender"/>
</root>
</configuration>
代码:
@Test
public void test02(){
Logger logger = LoggerFactory.getLogger(LogBackTest.class);
for (int i = 0; i < 50; i++) {
logger.trace("trace追踪信息");
logger.debug("debug详细信息"); // 默认级别
logger.info("info关键信息");
logger.warn("warn警告信息");
logger.error("error错误信息");
}
for (int i = 0; i < 5; i++) {
System.out.println("——————————————"+i);
}
}
运行结果:
...
[DEBUG] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] debug详细信息
——————————————0
[INFO ] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] info关键信息
——————————————1
——————————————2
[WARN ] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] warn警告信息
[ERROR] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] error错误信息
——————————————3
[TRACE] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] trace追踪信息
——————————————4
[DEBUG] 2023-06-06 22:11:20.279 [main] [com.xb.LogBackTest#?-?] debug详细信息
...
7、自定义记录器
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 配置自定义日志输出格式 -->
<property name="pattern" value="[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] [%t] [%c#%M-%L] %m%n"/>
<!-- 配置控制台输出器 -->
<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 配置日志字体颜色,默认黑色(System.out),红色(System.err) -->
<target>System.err</target>
<!-- 配置日志输出格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<!-- 引用自定义日志输出格式 -->
<pattern>${pattern}</pattern>
</encoder>
</appender>
<!-- 配置自定义记录器 -->
<logger name="com.logback" level="info" additivity="false">
<appender-ref ref="consoleAppender"/>
</logger>
</configuration>
代码:
@Test
public void test01() {
Logger logger = LoggerFactory.getLogger(LogbackTest.class);
logger.trace("trace追踪信息");
logger.debug("debug详细信息");
logger.info("info关键信息");
logger.warn("warn警告信息");
logger.error("error错误信息");
}
运行结果:
[2022-07-02 11:31:12.659] [INFO ] [main] [com.logback.LogbackTest#test01-14] info关键信息
[2022-07-02 11:31:12.661] [WARN ] [main] [com.logback.LogbackTest#test01-15] warn警告信息
[2022-07-02 11:31:12.661] [ERROR] [main] [com.logback.LogbackTest#test01-16] error错误信息
问题:如果系统以前是使用Log4j的日志框架,如何将配置文件转换xml?--logback官网可以转换