简体   繁体   English

NHibernate和拦截器 - 测量/监控SQL往返时间

[英]NHibernate and interceptors - measuring/monitoring SQL round-trip times

In order to get early-warning of a slow or potentially slow areas, I'd like to have an Interceptor for NHibernate that can act as a performance monitor, so that any database operation that takes more than a given time raises an event and (importantly) a full stacktrace into the application's logs. 为了获得缓慢或潜在缓慢区域的早期警告,我想要一个可以作为性能监视器的NHibernate Interceptor,这样任何超过给定时间的数据库操作都会引发一个事件和(重要的是)应用程序日志中的完整堆栈跟踪。

Interceptors seemed to be a good window into this. 拦截器似乎是一个很好的窗口。 However, having experimented, there doesn't seem to be anyway to catch a "just-back-from-SQL" event: 但是,经过实验,似乎没有任何方法可以捕获“刚从SQL返回”事件:

  • OnPreFlush and OnPostFlush work on full batches where writes are involved, but aren't invoked on read events. OnPreFlushOnPostFlush适用于涉及写入的完整批处理,但不会在读取事件上调用。
  • OnPrepareStatement() seems to be the best to put start measuring, but to stop? OnPrepareStatement()似乎是最好的开始测量,但要停止?
  • For read events, OnLoad might be the place to stop the clock, but it's called once-per-entity returned - how do I know when I've got to the end of all entities? 对于读取事件, OnLoad可能是停止时钟的地方,但它被称为每个实体返回一次 - 我如何知道何时到达所有实体的末尾?
  • For write events, I can't see any post-SQL event (other than those that work on the entire batch - OnPostFlush and OnAfterTransaction ; I get the impression OnSave , OnFlushDirty , etc are called before the actual database call occurs - happy to be corrected though). 对于写事件,我看不到任何post-SQL事件(除了那些适用于整个批处理的事件 - OnPostFlushOnAfterTransaction ;我得到印象OnSaveOnFlushDirty等在实际数据库调用发生之前被调用 - 很高兴成为虽然纠正了)。

From what I can tell, documentation is heavily lacking on exactly what the pipeline order is with NHibernate's interaction with the database, and thus when in that pipeline different events and interceptor calls are called in relation to the actual SQL execution itself. 据我所知,文档严重缺乏NHibernate与数据库交互的管道顺序,因此在该管道中,与实际的SQL执行本身相关地调用不同的事件和拦截器调用。

This is something that needs to be permanently available, sitting in the background, pretty much that requires no human intervention except when slow queries are detected. 这是需要永久可用的东西,坐在后台,几乎不需要人为干预,除非检测到慢速查询。 It also needs to run headless on a large farm of servers, so interactive tools such as NHibernate Profiler are out: it's literally something that we can enable and forget about, letting it log as and when appropriate. 它还需要在大型服务器场上无头运行,因此NHibernate Profiler等交互式工具已经出局了:它实际上是我们可以启用和忘记的东西,让它在适当的时候记录。

Is there anything I have missed or misunderstood? 有什么我错过或误解了吗?

I had a similar problem. 我遇到了类似的问题。 I wanted measure and log all queries that goes through NHibernate. 我想要测量并记录通过NHibernate的所有查询。 What I did is I wrote a custom batching factory (in this case I work with oracle) but you can apply the same technique to any db: 我做的是我写了一个自定义的批处理工厂(在这种情况下我使用oracle)但你可以将相同的技术应用于任何db:

1-) Implement batcher factory, (in this case I am extending existing factory) 1-)实施配料工厂,(在这种情况下,我正在扩展现有工厂)

public class OracleLoggingBatchingBatcherFactory : OracleDataClientBatchingBatcherFactory
{
    public override IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
    {
        return new OracleLoggingBatchingBatcher(connectionManager, interceptor);
    }
}

2-) Implement the Batcher itself (in this case I am extending existing batcher). 2-)实现Batcher本身(在这种情况下,我正在扩展现有的batcher)。 Make sure you inherit IBatcher again since we want our new methods to be called 确保再次继承IBatcher,因为我们希望调用新方法

public class OracleLoggingBatchingBatcher : OracleDataClientBatchingBatcher, IBatcher
{
      .... // here override ExecuteNonQuery, DoExecuteBatch and ExecuteReader. 
           //You can do all kind of intercepting, logging or measuring here
           //If they are not overrideable just implement them and use "new" keyword if necessary
           //since we inherit IBatcher explicitly it will work polymorphically.
           //Make sure you call base implementation too or re-implement the method from scratch
}

3-) Register the factory via NHibernate config: 3-)通过NHibernate配置注册工厂:

    <property name="adonet.factory_class">OracleLoggingBatchingBatcherFactory, MyAssembly</property>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM