logback logger 的疑惑

本文解析了Logback中日志级别的工作原理,特别是当根logger级别设为INFO时为何还能输出DEBUG级别日志的原因。通过理解logger层级结构及appender附加性,解释了这一现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序代码:

package logback;

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

public class LogbackDemo {

	private static Logger log = LoggerFactory.getLogger(LogbackDemo.class);

	public static void main(String[] args) {
		log.trace("======trace");
		log.debug("======debug");
		log.info("======info");
		log.warn("======warn");
		log.error("======error");
	}

}

logback-test.xml

<configuration scan="false">
	<property name="module_name" value="test" />
	<timestamp key="time_pattern" datePattern="yyyy-MM-dd HH:mm:ss" />
	<contextName>${module_name}-${time_pattern}</contextName>
	
	<appender name="FILE_1" class="ch.qos.logback.core.FileAppender">
		<file>logs/file1.log</file>
		<append>false</append>
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>
	
	<appender name="FILE_2" class="ch.qos.logback.core.FileAppender">
		<file>logs/file2.log</file>
		<append>false</append>
		<encoder>
			<pattern>%d [%-5level] %file,%line - %msg%n</pattern>
		</encoder>
	</appender>
	
	<logger name="logback" level="DEBUG">
		<appender-ref ref="FILE_2" />
	</logger>
	
	<root level="INFO">
		<appender-ref ref="FILE_1" />
	</root>
	
</configuration>

日志输出结果:

file1.log

15:29:44.306 [main] DEBUG logback.LogbackDemo - ======debug
15:29:44.308 [main] INFO  logback.LogbackDemo - ======info
15:29:44.308 [main] WARN  logback.LogbackDemo - ======warn
15:29:44.309 [main] ERROR logback.LogbackDemo - ======error

file2.log

2016-06-15 15:29:44,306 [DEBUG] LogbackDemo.java,12 - ======debug
2016-06-15 15:29:44,308 [INFO ] LogbackDemo.java,13 - ======info
2016-06-15 15:29:44,308 [WARN ] LogbackDemo.java,14 - ======warn
2016-06-15 15:29:44,309 [ERROR] LogbackDemo.java,15 - ======error

问题: LogbackDemo类输入logback包,所以logger (logback) 输出DEBUG所有信息,这个好理解,但是ROOT level是INFO,却输出了DEBUG级别的所有日志,这个有些费解?


要找到问题的答案,首先要看看logback的官方文档。以下时重点部分:

  • Named Hierarchy

A logger is said to be an ancestor of another logger ifits name followed by a dot is a prefix of the descendantlogger name. A logger is said to be a parent of a childlogger if there are no ancestors between itself and thedescendant logger.


  • Logger Hierarchy

The effective level for a given logger L, is equalto the first non-null level in its hierarchy, starting atL itself and proceeding upwards in the hierarchytowards the root logger.


  • Logging request selection

A log request of level p issued to a logger havingan effective level q, is enabled ifp >= q.


  • AppenderAdditivity

The output of a log statement of logger L will go toall the appenders inL and its ancestors. This is themeaning of the term "appender additivity".

However, if an ancestor of logger L, say P,has the additivity flag set to false, thenL's outputwill be directed to all the appenders inL and itsancestors up to and includingP but not the appenders inany of the ancestors ofP.

Loggers have their additivity flag set to true by default.


其中问题的重点就在第四项, appender additivity, 意思就是当前logger的appender additivity 若是没有显式设置为false,则默认把parent logger的appender加入到自己的appender列表里。


当前logger (logback.LogbackDemo) 没有显示设置level和additivity属性,那么继承parent logger (logback)的LEVEL 和 additivity 属性, LEVEL = DEBUG, additivity = true, 那么logger (logback) 的appender有哪些呢? 除了自己设定的file1, 因为additivity = true,还包含ROOT的appender file2, 所以logger (logback.LogbackDemo) 继承自父类 logger level = DEBUG, appender= file1, file2;


结果就是上面的样子了。


参考资料: http://logback.qos.ch/manual/architecture.html

### 配置和使用 Logback Logger #### 添加依赖项 为了在项目中使用Logback,需要先添加Maven或Gradle中的相应依赖。对于Maven而言,在`pom.xml`文件内加入以下片段: ```xml <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.10</version> </dependency> ``` 这一步骤确保了Logback库被正确引入到工程之中[^1]。 #### 创建 logback.xml 文件 接着应当创建名为 `logback.xml` 的配置文件并放置于项目的资源目录下(通常是 `src/main/resources/`),该文件定义了日志的行为模式以及输出格式等内容。下面是一个简单的例子展示如何设置不同级别的日志输出至控制台与文件,并且实现了按天滚动存储的功能[^4]。 ```xml <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 定义日志文件路径 --> <property name="LOG_PATH" value="./logs"/> <!-- 控制台Appender --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <!-- 日志文件Appender, 每天生成一个新的日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/application.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <!-- daily rollover --> <fileNamePattern>${LOG_PATH}/archived/application-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern> <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> <maxFileSize>10MB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy> </rollingPolicy> <encoder> <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> </encoder> </appender> <!-- 设置根Logger,默认级别为INFO --> <root level="info"> <appender-ref ref="STDOUT"/> <appender-ref ref="FILE"/> </root> </configuration> ``` 上述XML文档设置了两个appenders:一个是用于向标准输出打印信息;另一个则是负责将日志写入磁盘上的文件中去。同时指定了当达到一定大小时自动分割旧的日志文件,并压缩存档以节省空间[^3]。 #### 使用 Logger 对象记录日志 完成以上准备工作之后就可以开始编写Java代码来实际调用这些配置好的设施了。通常情况下会通过SLF4J API来进行操作而不是直接针对具体的实现类,这样做可以让程序更加解耦合易于维护。 ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Example { private static final Logger logger = LoggerFactory.getLogger(Example.class); public void someMethod() { String message = "This is a test message."; logger.debug("Debugging information."); logger.info(message); logger.warn("Warning occurred while processing request."); logger.error("Error encountered during operation.", new Exception("Sample exception")); } } ``` 这段代码展示了四种常见的日志等级——DEBUG、INFO、WARN 和 ERROR ——它们分别对应不同程度的重要性或是严重性的事件报告给开发者或者运维团队成员查看。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值