Hibernating Rhinos

Zero friction databases

Use ProfilerIntegration static class in order to hook into the profiler

A user asked us how can he use this class so I thought it may be a good idea to blog about that.

You can use the HibernatingRhinos.Profiler.Appender.ProfilerIntegration static class in order to hook into the profiler and do some interesting staff.

The two most uses of this class is 1. telling the profiler to ignore some code and not record it. 2. record something that wasn’t executed by the ORM but by ADO.NET directly in the profiler.

Ignore and not profile a portion of code

This is mostly useful when running unit tests and you need to do some initialization to the database which you prefer not to see in the profiler output.

You can do this using:

using (ProfilerIntegration.IgnoreAll())
{
    // Do something
}

Or

ProfilerIntegration.IgnoreAll();
// Do something
ProfilerIntegration.ResumeProfiling();

Record custom messages inside the profiler

This is mostly useful if you doing some use of the pure ADO.NET api alongside to the ORM that you’re using and you want to record those actions.

In this case, since you aren’t using the DbConnection/DbDataReader/DbCommnad etc that the profiler created, you’ll need to notify the profiler about each action.

This can be done using the following code:

ProfilerIntegration.PublishProfilerEvent("session id", "logger name", "message");

This is 3 parameters:

Session ID = a string that identify the session to which this statement belongs. In NHibernate you’ll want to use ((SessionImpl)session).SessionId.ToString(). In the other ORM, you can use some GUID which should be the same for statements in this session.

Logger name = specifies the log type. This is ORM specific, in NHibernate you’ll use "NHibernate.SQL" in order to log a statement while that in EF this will be "EntityFramework.Sql".

Message = The actual message to record. If this an SQL statement, you’ll provide the SQL statement here.

Example:

            const string sql =
                @"SELECT
        first 5 this_.LOG_ID as LOG1_0_0_,
        this_.LOG_DATE as LOG2_0_0_,
        this_.APP_NAME as APP3_0_0_,
        this_.LOGGER as LOGGER0_0_,
        this_.LOG_LEVEL as LOG5_0_0_,
        this_.MESSAGE as MESSAGE0_0_,
        this_.EXCEPTION_MESSAGE as EXCEPTION7_0_0_,
        this_.CONTEXT as CONTEXT0_0_
FROM APP_LOG this_ ORDER BY this_.LOG_DATE desc";

            using (var s = (SessionImpl)factory.OpenSession())
            {
                ProfilerIntegration.PublishProfilerEvent(
                    s.SessionId.ToString(),
                    "NHibernate.SQL",
                    sql);
            }

PublishProfilerEvent is really low level API. If you’re using Entity Framework Profiler you can use the EntityFrameworkAppender class which provides more high level API:

   1:  var sessionId = Guid.NewGuid();
   2:  var entityFrameworkAppender = new EntityFrameworkAppender("My app");
   3:  entityFrameworkAppender.ConnectionStarted(sessionId);
   4:  var statementId = Guid.NewGuid();
   5:  entityFrameworkAppender.StatementExecuted(sessionId, statementId, "Select ...");
   6:  entityFrameworkAppender.StatementRowCount(sessionId, statementId, 8);
   7:  entityFrameworkAppender.StatementError(sessionId, new InvalidOperationException("Report an error to the profiler"));
   8:  entityFrameworkAppender.ConnectionDisposed(sessionId);

But this is considered internal API which may be changed.

NHibernateProfiler doesn’t expose a high level API like this, so you’ll need to call ProfilerIntegration.PublishProfilerEvent with the correct logger name. If you would like to know a particular logger name you can email us and we’ll provide you with the information that you need.

Tags:

Posted By: Fitzchak Yitzchaki

Published at

Originally posted at

Comments

No comments posted yet.

Comments have been closed on this topic.