Hibernate统计日志记录

时间:2017-03-30 13:54:48

标签: oracle hibernate session logging jdbc

我对解释hibernate会话日志有点困惑。 我的主要问题是许多查询都很慢 - 基于我实现的一些TimeWatch记录。 为了进一步追踪问题,我已经启用了hibernate会话日志记录,目的是查看执行查询或获取连接的时间是否丢失(这意味着错误配置,我猜)。

关于用例的一点点 - Oracle DB,Spring,Hibernate。在“繁忙时期”,有一个最大值。 15个线程对数据库执行查询。所以没什么特别的,我猜。

现在我看到hibernate会话日志,如。

2017-03-30 13:35:13.834+0200 [process-documents-task-6] I [/] o.h.e.i.StatisticalLoggingSessionEventListener - Session Metrics {
    636713687 nanoseconds spent acquiring 1 JDBC connections;
    57993 nanoseconds spent releasing 1 JDBC connections;
    636859879 nanoseconds spent preparing 1 JDBC statements;
    2231526 nanoseconds spent executing 1 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;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    9261 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)

2017-03-30 13:35:16.073+0200 [process-documents-task-8] I [/] o.h.e.i.StatisticalLoggingSessionEventListener - Session Metrics {
    2893793341 nanoseconds spent acquiring 1 JDBC connections;
    22196 nanoseconds spent releasing 1 JDBC connections;
    2893869403 nanoseconds spent preparing 1 JDBC statements;
    1509926 nanoseconds spent executing 1 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;
    0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
    4056 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)

但究竟是什么意思?

我目前的解释

  • 执行查询的1509926纳秒(1.5毫秒):似乎没问题
  • 2893793341纳秒获取连接(2.8秒):不行 :(
  • 2893869403纳秒准备声明(2.8秒):不行 :(

准备声明是什么意思? 根据我从javadoc中读取的内容,它可能意味着将查询发送到数据库进行优化。 但为什么它总是在获取连接需求的时候呢?

有关如何追查问题,根本原因的任何建议吗?

或者问题可能是什么提示?

感谢您的帮助!

祝你好运, 斯蒂芬

1 个答案:

答案 0 :(得分:0)

默认的Hibernate统计信息不是很有用。我们计划在未来的Hibernate版本中增强这一方面。

但是,正如我在my book中所解释的那样,您可以提供基于Dropwizard Metrics构建的自己的Statistics实现。

简而言之,假设您有TransactionStatistics类扩展org.hibernate.stat.internal.ConcurrentStatisticsImpl

public class TransactionStatistics extends ConcurrentStatisticsImpl {

    private static final ThreadLocal<AtomicLong> startNanos = new ThreadLocal<AtomicLong>() {
        @Override protected AtomicLong initialValue() {
            return new AtomicLong();
        }
    };

    private static final ThreadLocal<AtomicLong> connectionCounter = new ThreadLocal<AtomicLong>() {
        @Override protected AtomicLong initialValue() {
            return new AtomicLong();
        }
    };

    private StatisticsReport report = new StatisticsReport();

    @Override public void connect() {
        connectionCounter.get().incrementAndGet();
        startNanos.get().compareAndSet(0, System.nanoTime());
        super.connect();
    }

    @Override public void endTransaction(boolean success) {
        try {
            report.transactionTime(System.nanoTime() - startNanos.get().get());
            report.connectionsCount(connectionCounter.get().get());
            report.generate();
        } finally {
            startNanos.remove();
            connectionCounter.remove();
        }
        super.endTransaction(success);
    }
}

您需要创建StatisticsFactory实施:

public class TransactionStatisticsFactory implements StatisticsFactory {

    @Override
    public StatisticsImplementor buildStatistics(SessionFactoryImplementor sessionFactory) {
        return new TransactionStatistics();
    }
}

并按照以下方式配置:

Etvoilà!

现在,您可以监控统计数据并将其导出为Dropwizard Metrics支持的任何格式。而且,Dropwizard Metrics使用各种水库,因此您可以根据用例选择最佳水库。

要查看Dropwizard Metrics的真正威力,请查看FlexyPool