I am pretty fond of the way NH Prof is architected. At a very high level, it looks like this:
The first part isn’t really that interesting, the main challenge is to get the data from your application to the profiler in as speedy and performant way as possible. We are using a binary protocol based on Protocol Buffers with TCP Sockets as the communication mechanism.
Next we have the listener and the message processors. That is where a lot of the magic actually happens, we do first level analysis on the incoming log messages and transform them into higher level concepts. At this point, we are only dealing with a single message, we have no overall picture, but a lot of work is actually happening at this layer.
It is there that I normalize the differences between all the NHibernate versions that I support and make sure that the other layers work on a common object model.
The next stage is the model building, where I am actually taking all the information and start putting it together, it is there where concepts such as sessions, and statements in session start making sense, it is there that I actually apply analytics to provide you with the alerts. It is a pretty complex piece of code, taken together, but each individual part is pretty simple.
Next, we have the view model, which is another representation of the model in a format that is applicable for showing to the user, I have spoke before about moving from a push to a pull model, in order to allow the UI to remain performant. That has been one of the major challenges in that area. Well, that and making sure that we have good UX.
The interesting part about this architecture is that a new feature is usually something that happen either in the listeners and the model building (when it match the current model that we have) or a vertical slice across the entire layer, when we need to express some new concept.
More posts in "NH Prof" series:
- (09 Dec 2010) Alert on bad ‘like’ query
- (10 Dec 2009) Filter static files
- (16 Nov 2009) Exporting Reports
- (08 Oct 2009) NHibernate Search Integration
- (19 Aug 2009) Multiple Session Factory Support
- (07 Aug 2009) Diffing Sessions
- (06 Aug 2009) Capturing DDL
- (05 Aug 2009) Detect Cross Thread Session Usage
- (22 May 2009) Detecting 2nd cache collection loads
- (15 May 2009) Error Detection
- (12 May 2009) Queries by Url
- (04 Feb 2009) View Query Results
- (18 Jan 2009) Superfluous <many-to-one> update
- (18 Jan 2009) URL tracking
- (10 Jan 2009) Detecting distributed transactions (System.Transactions)
- (06 Jan 2009) The Query Cache
- (05 Jan 2009) Query Duration
- (24 Dec 2008) Unbounded result sets
- (24 Dec 2008) Row Counts