当配置 org.hibernate.SQL 记录器时,Logback 显示带有根级别 INFO 的 DEBUG 输出
Posted
技术标签:
【中文标题】当配置 org.hibernate.SQL 记录器时,Logback 显示带有根级别 INFO 的 DEBUG 输出【英文标题】:Logback shows DEBUG output with root at level INFO when org.hibernate.SQL logger configured 【发布时间】:2019-02-22 14:27:51 【问题描述】:为什么 logback 允许通过设置为级别 INFO 的根记录器进行 DEBUG 输出?
上下文是一个使用 Hibernate 的 spring-boot-starter 项目。 POM 在 1.2.0 版本中命名为 logback-classic 和 logback-core。以下配置文件位于其类路径(src/main/resources)中,将根记录器设置为 INFO 级别。
logback-test.xml:
<configuration scan="true" debug="false">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/test.log</file>
<encoder>
<pattern>%d"yyyy-MM-dd'T'HH:mm:ss.SSSXXX", UTC [%thread] %-5level %logger5 - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<logger name="org.hibernate.SQL" level="DEBUG" />
</configuration>
在 JUnit 测试期间,文件中会出现大量 INFO/WARN/ERROR 消息。但我很惊讶地看到来自 org.hibernate.SQL 的以下 DEBUG 输出,这是唯一提供调试级输出的包。我想我必须将根记录器设置为 DEBUG 级别才能允许这样做;我认为级别 INFO 会阻止它:
2018-09-18T13:31:02.596Z [http-nio-auto-1-exec-4] DEBUG o.h.SQL - delete from C_NOTIF_XYZ where ID=?
在幕后,Hibernate 似乎通过注释使用 org.jboss.logging.Logger,请参阅https://github.com/hibernate/hibernate-orm/blob/master/hibernate-core/src/main/java/org/hibernate/internal/CoreLogging.java
由于使用了注释,我不确定是否找到了创建上面显示的删除输出的确切类。我从谷歌搜索中看到,有些人建议记录 shim 类的交互;但我不确定。
非常相似的 SO 问题(所以我并不孤单:)但没有答案:Using logback, debug messages are still being logged though root level is set to "Error"
提前感谢任何提示。
【问题讨论】:
【参考方案1】:目前我没有找到对文档的参考,但我确认了这种操作模式:通过可加性达到的祖先记录器的行为,默认情况下设置为 true,跳过日志级别检查。 然后无论日志级别如何,日志消息都会发送到根日志记录器。
【讨论】:
我没有问关于加法的问题。我完全不明白这个答案。 在您的 logback-test.xml 配置文件中将 additivity 设置为 false 以停止“传播”到根记录器,如答案中所述,在传播日志的情况下不检查日志级别,总是要写已经到达的消息。此配置将停止写入根记录器: ...来自the docs:
给定记录器 L 的有效级别等于其层次结构中的第一个非空级别,从 L 本身开始,并在层次结构中向上到根记录器。
因此,您可以为记录器定义一个覆盖根级别的有效级别。您看到的行为是默认的 Logback 行为。
如果您想禁用来自org.hibernate.SQL
logger 的 DEBUG 日志记录,那么:
org.hibernate.SQL
记录器配置,因为这将导致org.hibernate.SQL
记录器采用root
记录器级别
为org.hibernate.SQL
logger 分配除DEBUG 以外的日志级别
【讨论】:
logger org.hibernate.SQL 的有效级别实际上是 DEBUG(直接设置)还是 INFO(设置在 root 上)? 在您的配置中,org.hibernate.SQL
的有效级别是 DEBUG
,因为该级别设置在层次结构中低于 root
级别 INFO
的位置。 docs 中有四个有用的示例(以表格形式)显示了如何确定有效级别。
我想我将继承/有效级别与过滤器/截止级别混淆了。我现在了解根配置在所有记录器上设置了默认有效级别。因此,通过有效的级别调试,org.hibernate.SQL 记录器让 DEBUG 及更高版本通过。我的文件附加程序没有过滤器子句,因此这些事件出现在输出中。这是思考这个案子的正确方式吗?
您的文件附加程序没有过滤子句,因此它将接受日志子系统提供的任何内容。日志子系统将为它提供级别 >= INFO 的日志事件和由org.hibernate.sql
发出的级别 >= DEBUG 的所有日志事件。【参考方案3】:
删除这一行:
<logger name="org.hibernate.SQL" level="DEBUG" />
【讨论】:
是的,谢谢,我发现删除该行确实会抑制调试输出,但想了解原因。 他们使用的 JBoss 记录器与许多其他日志记录框架兼容,如果它不是主要使用的,则向他们发送日志消息,例如当它是库的一部分时休眠。在我从事的一个项目中,我在启动时添加了System.setProperty("org.jboss.logging.provider", "slf4j");
,它使 JBoss 记录器将消息发送到正在使用的任何 SLF4J 实现。很可能,Spring 要么告诉它使用 logback,要么它自动检测到它。
至于为什么采用该设置,而不是root
,root
定义了它默认的最低优先级值,并且这些消息具体发送到org.hibernate.SQL
,它有更高的优先级设置。以上是关于当配置 org.hibernate.SQL 记录器时,Logback 显示带有根级别 INFO 的 DEBUG 输出的主要内容,如果未能解决你的问题,请参考以下文章
如何计算 Hibernate 在一个 Grails 请求中执行了多少 SQL 查询?