欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Hibernate 4、5 和 6 的日志指南--在开发和生产中使用正确的配置

最编程 2024-07-04 12:34:19
...
  • 鸣叫
  • 分享
  • 分享
  • 分享
  • 电子邮件

选择正确的日志配置可以在开发过程中发现性能问题或在生产中受到影响之间做出区别。但它也会产生开销,使你的应用程序变慢。你需要决定你需要哪些信息并相应地配置你的系统。

因此,我更喜欢使用两种不同的配置。

  1. 开发配置需要记录足够的内部信息,以了解数据库的互动,看到执行的查询数量,并检查SQL语句。
  2. 生产配置应该通过记录尽可能少的信息来避免任何开销。

而除了目标系统之外,你的配置也取决于你所使用的Hibernate版本。对于你的开发配置来说更是如此。一些日志功能,比如慢速查询日志,在旧的Hibernate版本中是不可用的,而且Hibernate 6改变了几个重要的日志类别的名称。

正因为如此,我将解释不同的日志类别,并为你提供我在使用Hibernate 4、5和6时推荐的开发和生产日志配置。

内容

  • 1支持的日志后端
  • 2日志类别
  • 3不要使用show_sql来记录SQL查询
  • 4推荐的日志配置
    • 4.1发展
      • 4.1.1Hibernate 4、5和6的Log4J配置
      • 4.1.2用于Hibernate 4、5和6的Log4J2配置
      • 4.1.3用于Hibernate 4、5和6的JDK日志器配置
      • 4.1.4Hibernate 4、5和6的Logback via Slf4j配置
      • 4.1.5Hibernate 4和5的日志示例
      • 4.1.6Hibernate 6的日志示例
    • 4.2生产
      • 4.2.1Log4J
      • 4.2.2Log4J2
      • 4.2.3JDK日志器
      • 4.2.4通过Slf4j的日志反馈
  • 5总结

支持的日志后端

在我们看不同的日志类别和级别之前,让我们简单看一下Hibernate支持的日志框架。从4.0版本开始,Hibernate使用JBoss Logging库将消息写到日志文件中。这个库是一个日志桥,可以整合不同的日志框架。你可以决定在你的应用程序中使用以下哪个框架。

  1. JBoss LogManager
  2. Log4j 2
  3. Log4j 1
  4. Slf4j
  5. JDK日志

你只需要把你喜欢的框架添加到classpath中,JBoss Logging库就会接收到它。如果有多个框架可用,它会选择优先级最高的那个。

所有框架的概念和日志类别都是一样的,但配置文件的格式和日志级别的名称可能不同。我将在本文中展示几个不同的配置文件。如果你的日志框架没有包括在内,请查看你的日志框架的文档。

日志类别

像所有的应用程序和框架一样,Hibernate将日志信息写在不同的类别和日志级别中。

这些类别对特定主题的日志信息进行分组,如执行的SQL语句或缓存交互。下表显示了Hibernate使用的最重要的日志类别。

类别 描述
org.hibernate 这个类别包含Hibernate写的所有消息。你可以用它来分析不特定的问题或找到Hibernate使用的类别。
将此类别设置为精细的日志级别可能会产生大量的日志输出。
org.hibernate.SQL 所有通过JDBC执行的SQL语句都被写入这个类别。你可以把它和org.hibernate.type.descriptor.sqlorg.hibernate.orm.jdbc.bind一起使用,以获得关于JDBC参数和结果的更多信息。
org.hibernate.type.descriptor.sql Hibernate 4和5
Hibernate将绑定到JDBC参数和从JDBC结果中提取的值写入该类别。这个类别应该和org.hibernate.SQL一起使用,以便同时记录SQL语句。
org.hibernate.orm.jdbc.bind Hibernate 6
Hibernate将绑定到JDBC参数的值写到这个类别。这个类别应该和org.hibernate.SQL一起使用,以便同时记录SQL语句。
org.hibernate.SQL_SLOW Hibernate >= 5.4.5
如果一个SQL语句的执行时间超过配置的阈值,Hibernate会向慢速查询日志写一条消息(见慢速查询日志)。
org.hibernate.pretty Hibernate将刷新时的状态记录到最大。20个实体到这个类别。
org.hibernate.cache 关于二级缓存活动的信息被写入这个类别。
org.hibernate.stat Hibernate会将每次查询的一些统计数据写到这个类别中。这些统计数据需要单独激活(见激活Hibernate统计)。
org.hibernate.hql.internal.ast.AST Hibernate 4和5
这个类别在查询解析过程中对HQL和SQL AST进行分组。
org.hibernate.tool.hbm2ddl Hibernate将模式迁移过程中执行的DDL SQL查询写到这个日志类别。

日志级别的名称是由你的日志框架定义的,并定义了日志信息的数量和颗粒度。你可以为每个类别指定一个日志级别。如果你没有为一个特定的类别指定一个日志级别,它将从它的父类别继承这个级别。

不要使用show_sql来记录SQL查询。

如何让Hibernate记录执行的SQL查询是一个经常被问到的问题,互联网上最流行的答案似乎是将persistence.xml中的show_sql参数设置为true。但是,请不要这样做!

Hibernate提供了两种方法来激活执行的SQL查询的日志,而将show_sql参数设置为true是最糟糕的一种。它有两个巨大的缺点。

  1. Hibernate将所有执行的SQL语句写入标准输出,而不使用日志框架。因此,定义包含这些特定日志信息的日志文件变得很困难。写入标准输出往往比使用优化的日志框架要慢得多。
  2. persistence.xml是你的应用程序的jar文件的一部分,如果你想激活或停用SQL语句的日志,你需要打开这个二进制文件。你的日志框架的配置通常是一个外部文本文件,在任何系统上都可以很容易地改变。

激活执行的SQL语句的日志的更好方法是将org.hibernate.SQL类别的日志级别设置为DEBUG(或你的日志框架的相应日志级别)。Hibernate将写入SQL语句,但不包含任何关于绑定到JDBC参数或从查询结果中提取的值的信息。如果你也想获得这些信息,你必须将org.hibernate.type.descriptor.sql的日志级别设置为DEBUG (见开发建议中的例子)。

推荐的日志配置

生产系统和开发系统的要求是非常不同的。在开发过程中,你需要知道Hibernate在后台做什么。但记录这些信息会降低应用程序的速度,而且在生产中也不需要。因此,我建议使用两种不同的设置。

开发

Hibernate在后台为你做很多事情,这让你很容易忘记你还在和数据库一起工作。但是,如果你想确保你的应用程序将按照你的预期执行,你需要检查执行的查询数量和它们的SQL语句。

你需要将org.hibernate.SQL类别的日志级别设置为DEBUG来获得这些信息。如果你还想记录所使用的绑定参数值,你还需要将org.hibernate.type.descriptor.sql类别(Hibernate 4 & 5)或org.hibernate.orm.jdbc.bind类别(Hibernate 6)设为跟踪

除此之外,我更喜欢激活Hibernate统计,以便在每个会话结束时获得最关键指标的总结。而如果你使用的Hibernate至少是5.4.5版本,我还建议激活Hibernate的慢速查询日志

你可以在下面的章节中看到不同日志框架的这种日志配置。

用于Hibernate 4、5和6的Log4J配置

###
# Global configuration for all Hibernate versions
###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n

log4j.rootLogger=info, stdout

###
# Hibernate < 5.4.5
###
# basic log level for all messages
log4j.logger.org.hibernate=info
# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type.descriptor.sql=trace
# Statistics
log4j.logger.org.hibernate.stat=debug
# 2nd Level Cache
log4j.logger.org.hibernate.cache=debug

###
# Hibernate >= 5.4.5
###
# basic log level for all messages
log4j.logger.org.hibernate=info
# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.type.descriptor.sql=trace
# Statistics and slow queries
log4j.logger.org.hibernate.stat=debug
log4j.logger.org.hibernate.SQL_SLOW=info
# 2nd Level Cache
log4j.logger.org.hibernate.cache=debug

###
#Hibernate >= 6
###
# basic log level for all messages
log4j.logger.org.hibernate=info
# SQL statements and parameters
log4j.logger.org.hibernate.SQL=debug
log4j.logger.org.hibernate.orm.jdbc.bind=trace
# Statistics and slow queries
log4j.logger.org.hibernate.stat=debug
log4j.logger.org.hibernate.SQL_SLOW=info
# 2nd Level Cache
log4j.logger.org.hibernate.cache=debug

用于Hibernate 4、5和6的Log4J2配置

<Configuration monitorInterval="60">
    <Properties>
        <Property name="log-path">PropertiesConfiguration</Property>
    </Properties>
    <Appenders>
        <Console name="Console-Appender" target="SYSTEM_OUT">
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>>
            </PatternLayout>
        </Console>
    </Appenders>
    <Loggers>
        <! – Hibernate before 5.4.5 – >
        <Logger name="org.hibernate.SQL" level="debug" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.stat" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.cache" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>

        <! – Hibernate after 5.4.5 – >
        <Logger name="org.hibernate.SQL" level="debug" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.stat" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.SQL_SLOW" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.cache" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>

        <! – Hibernate after 6 – >
        <Logger name="org.hibernate.SQL" level="debug" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.orm.jdbc.bind" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.stat" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.SQL_SLOW" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Logger name="org.hibernate.cache" level="trace" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>

        <Root level="info">
            <AppenderRef ref="Console-Appender"/>
        </Root>
    </Loggers>
</Configuration>

适用于Hibernate 4、5和6的JDK日志器配置

###
# Global configuration for all Hibernate versions
###
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

org.hibernate.level=INFO

###
# Hibernate < 5.4.5
###
# basic log level for all messages
org.hibernate.SQL.level=FINER
org.hibernate.type.descriptor.sql.level=FINEST
# Statistics
org.hibernate.stat.level=FINER
# 2nd Level Cache
org.hibernate.cache.level=FINER

###
# Hibernate >= 5.4.5
###
# basic log level for all messages
org.hibernate.SQL.level=FINER
org.hibernate.type.descriptor.sql.level=FINEST
# Statistics
org.hibernate.stat.level=FINER
org.hibernate.SQL_SLOW.level=INFO
# 2nd Level Cache
org.hibernate.cache.level=FINER

###
# Hibernate >= 6
###
# basic log level for all messages
org.hibernate.SQL.level=FINER
org.hibernate.orm.jdbc.bind.level=FINEST
# Statistics
org.hibernate.stat.level=FINER
org.hibernate.SQL_SLOW.level=INFO
# 2nd Level Cache
org.hibernate.cache.level=FINER

Hibernate 4、5和6的Logback via Slf4j配置

<configuration>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<Pattern>
				%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
			</Pattern>
		</encoder>
	</appender>
    <! – Hibernate before 5.4.5 – >
	<logger name="org.hibernate.SQL" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.stat" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.cache" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>

    <! – Hibernate after 5.4.5 – >
	<logger name="org.hibernate.SQL" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.type.descriptor.sql" level="trace" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.stat" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.SQL_SLOW" level="info" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.cache" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>

    <! – Hibernate after 6 – >
	<logger name="org.hibernate.SQL" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.orm.jdbc.bind" level="trace" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.stat" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.SQL_SLOW" level="info" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<logger name="org.hibernate.cache" level="debug" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>

	<root level="info">
		<appender-ref ref="STDOUT"/>
	</root>
</configuration>

Hibernate 4和5的日志示例

如果你在Hibernate 4或5中使用这些配置中的任何一种,它将会写一个看起来与下面非常相似的日志文件。它是由log4j2和Hibernate 5编写的。该日志显示了一个会话的Hibernate消息,其中我持久化了2个新的作者实体,之后更新了其中一个实体,并选择了所有具有指定姓氏的作者

13:45:20,863 DEBUG [org.hibernate.SQL] - select nextval ('hibernate_sequence')
13:45:20,907 DEBUG [org.hibernate.SQL] - select nextval ('hibernate_sequence')
13:45:20,939 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)
13:45:20,950 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [Thorben]
13:45:20,951 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [VARCHAR] - [Janssen]
13:45:20,952 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [0]
13:45:20,953 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [4] as [BIGINT] - [1]
13:45:20,960 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)
13:45:20,960 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [Nicolia]
13:45:20,960 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [VARCHAR] - [Parlog]
13:45:20,961 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [0]
13:45:20,961 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [4] as [BIGINT] - [2]
13:45:21,488 DEBUG [org.hibernate.SQL] - update Author set firstName=?, lastName=?, version=? where id=? and version=?
13:45:21,494 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [Nicolai]
13:45:21,503 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [2] as [VARCHAR] - [Parlog]
13:45:21,505 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [3] as [INTEGER] - [1]
13:45:21,509 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [4] as [BIGINT] - [2]
13:45:21,510 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [5] as [INTEGER] - [0]
13:45:21,522 DEBUG [org.hibernate.SQL] - select author0_.id as id1_0_, author0_.firstName as firstNam2_0_, author0_.lastName as lastName3_0_, author0_.version as version4_0_ from Author author0_ where author0_.lastName=?
13:45:21,524 TRACE [org.hibernate.type.descriptor.sql.BasicBinder] - binding parameter [1] as [VARCHAR] - [Janssen]
13:45:21,531 TRACE [org.hibernate.type.descriptor.sql.BasicExtractor] - extracted value ([id1_0_] : [BIGINT]) - [1]
13:45:21,541 INFO  [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] - Session Metrics {
    71600 nanoseconds spent acquiring 1 JDBC connections;
    42200 nanoseconds spent releasing 1 JDBC connections;
    5946500 nanoseconds spent preparing 6 JDBC statements;
    9801200 nanoseconds spent executing 6 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    55887200 nanoseconds spent executing 2 flushes (flushing a total of 4 entities and 0 collections);
    27027800 nanoseconds spent executing 1 partial-flushes (flushing a total of 2 entities and 2 collections)
}

如果你不需要那么多信息,我建议删除org.hibernate.type.descriptor.sql类别的配置。这将删除显示绑定参数值的日志信息。正如你在日志文件中所看到的,这些是大部分写入的日志信息,而且这些信息太多,日志变得难以阅读。

Hibernate 6的日志示例

正如你在下面的片段中看到的,Hibernate 6写的日志看起来非常相似。如果你正在选择多个实体对象,它往往比早期Hibernate版本写的日志更容易阅读。这主要是因为org.hibernate.orm.jdbc.bind这个类别只包括绑定参数的日志信息,而不包括提取参数的日志信息。

如果你想减少信息量,你应该考虑停用org.hibernate.orm.jdbc.bind这个类别的跟踪日志。

15:37:21,600 DEBUG [org.hibernate.SQL] - select nextval('Author_SEQ')
15:37:21,609 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 2 milliseconds. SQL: 'select nextval('Author_SEQ')'
15:37:21,612 DEBUG [org.hibernate.SQL] - select nextval('Author_SEQ')
15:37:21,615 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 2 milliseconds. SQL: 'select nextval('Author_SEQ')'
15:37:21,902 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)
15:37:21,903 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [1] as [VARCHAR] - [Thorben]
15:37:21,903 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [2] as [VARCHAR] - [Janssen]
15:37:21,903 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [3] as [INTEGER] - [0]
15:37:21,904 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [4] as [BIGINT] - [1]
15:37:21,908 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 4 milliseconds. SQL: 'insert into Author (firstName, lastName, version, id) values ('Thorben', 'Janssen', 0, 1)'
15:37:21,911 DEBUG [org.hibernate.SQL] - insert into Author (firstName, lastName, version, id) values (?, ?, ?, ?)
15:37:21,911 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [1] as [VARCHAR] - [Nicolia]
15:37:21,911 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [2] as [VARCHAR] - [Parlog]
15:37:21,912 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [3] as [INTEGER] - [0]
15:37:21,912 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [4] as [BIGINT] - [2]
15:37:21,914 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 2 milliseconds. SQL: 'insert into Author (firstName, lastName, version, id) values ('Nicolia', 'Parlog', 0, 2)'
15:37:21,915 DEBUG [org.hibernate.SQL] - update Author set firstName=?, lastName=?, version=? where id=? and version=?
15:37:21,915 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [1] as [VARCHAR] - [Nicolai]
15:37:21,915 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [2] as [VARCHAR] - [Parlog]
15:37:21,916 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [3] as [INTEGER] - [1]
15:37:21,916 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [4] as [BIGINT] - [2]
15:37:21,916 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [5] as [INTEGER] - [0]
15:37:21,919 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 3 milliseconds. SQL: 'update Author set firstName='Nicolai', lastName='Parlog', version=1 where id=2 and version=0'
15:37:21,952 DEBUG [org.hibernate.SQL] - select a1_0.id,a1_0.firstName,a1_0.lastName,a1_0.version from Author a1_0 where a1_0.lastName=?
15:37:21,952 TRACE [org.hibernate.orm.jdbc.bind] - binding parameter [1] as [VARCHAR] - [Janssen]
15:37:21,959 INFO  [org.hibernate.SQL_SLOW] - SlowQuery: 6 milliseconds. SQL: 'select a1_0.id,a1_0.firstName,a1_0.lastName,a1_0.version from Author a1_0 where a1_0.lastName='Janssen''
15:37:21,964 DEBUG [org.hibernate.stat.internal.StatisticsImpl] - HHH000117: HQL: SELECT a FROM Author a WHERE a.lastName = :lastName, time: 26ms, rows: 1
15:37:21,972 INFO  [org.hibernate.engine.internal.StatisticalLoggingSessionEventListener] - Session Metrics {
    51899 nanoseconds spent acquiring 1 JDBC connections;
    30200 nanoseconds spent releasing 1 JDBC connections;
    419199 nanoseconds spent preparing 6 JDBC statements;
    21482801 nanoseconds spent executing 6 JDBC statements;
    0 nanoseconds spent executing 0 JDBC batches;
    0 nanoseconds spent performing 0 L2C puts;
    0 nanoseconds spent performing 0 L2C hits;
    0 nanoseconds spent performing 0 L2C misses;
    390499 nanoseconds spent executing 1 flushes (flushing a total of 2 entities and 2 collections);
    40233400 nanoseconds spent executing 1 partial-flushes (flushing a total of 2 entities and 2 collections)
}

生产

只要你不需要分析生产中的问题,你就应该尽可能少地记录信息。这可以通过将所有与Hibernate相关的日志类别设置为ERROR来实现,适用于所有Hibernate版本。你还应该确保Hibernate统计组件和慢速查询日志被停用。

Log4J

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%c] - %m%n

log4j.rootLogger=info, stdout
# basic log level for all messages
log4j.logger.org.hibernate=error

Log4J2

<Configuration monitorInterval="60">
    <Properties>
        <Property name="log-path">PropertiesConfiguration</Property>
    </Properties>
    <Appenders>
        <Console name="Console-Appender" target="SYSTEM_OUT">
            <PatternLayout>
                <pattern>
                    [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
                </pattern>>
            </PatternLayout>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="org.hibernate" level="error" additivity="false">
            <AppenderRef ref="Console-Appender"/>
        </Logger>
        <Root level="info">
            <AppenderRef ref="Console-Appender"/>
        </Root>
    </Loggers>
</Configuration>

JDK日志器

handlers=java.util.logging.ConsoleHandler

java.util.logging.ConsoleHandler.level=FINEST
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

org.hibernate.level=SEVERE

通过Slf4j进行日志回溯

<configuration>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<Pattern>
				%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
			</Pattern>
		</encoder>
	</appender>
	<logger name="org.hibernate" level="error" additivity="false">
		<appender-ref ref="STDOUT"/>
	</logger>
	<root level="info">
		<appender-ref ref="STDOUT"/>
	</root>
</configuration>

摘要

Hibernate支持几个日志提供者,你可以通过将其添加到你的应用程序的classpath中来选择你喜欢的一个。

日志信息被分组为不同的类别,你可以通过为每个类别指定一个日志级别来激活或停用它们。

编写日志信息和收集所需信息需要一些时间。因此,你应该在你的生产配置中关闭所有不必要的日志信息。

开发配置应该激活一些关键类别的调试日志,比如org.hibernate.SQL,我最常做的是激活Hibernate统计,以尽快发现潜在的性能问题

  • 鸣叫
  • 分享
  • 分享
  • 分享
  • 电子邮件

推荐阅读