Sunday, November 9, 2008

Monitoring Hibernate With Jopr

I have heard several people ask questions regarding how they can manage and monitor Hibernate from Jopr. Some have even asked how they can do this even if their Hibernate app is not running inside a JBossAS server instance (for example, within its own, standalone J2SE virtual machine).

Jopr today has the capability to manage/monitor Hibernate if its running inside Tomcat or JBossAS via its Hibernate plugin. It can even monitor more than one Hibernate application/JVM that is running on your machine, even if they are using different versions of Hibernate!

Today, I checked in code to the RHQ core and Jopr Hibernate plugin to have it also support Hibernate that is running in a standalone JVM (in fact, it can now support Hibernate running in any JVM, so long as it can remotely connect to the Hibernate Statistic MBean's MBeanServer).

This is such a cool feature, that I decided to "wink" it. Watch the flash demo to see how you can examine your Hibernate statistics in the Jopr GUI - things such as which queries were executed, how many times they were executed and how long it took to execute them; how many and which entities were created and deleted, etc. This is a very helpful set of features for developers - I can attest to that because I use this to examine the RHQ Server's own Hibernate usage.

There are a couple caveats:

First, the JVM that Hibernate is running in must have JMX remoting enabled and configured to accept connections from the agent. Google "com.sun.management.jmxremote" and read all about the settings used to configure this. The demo used something like this:


java -Dcom.sun.management.jmxremote.port=19988 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-jar helloworld.jar


Second, your application must have enabled the Hibernate Statistics MBean. This sounds obvious, but I guess I should explicitly mention it. If you don't tell Hibernate to turn on its statistics, you can't very well get any useful data from it. To do this, your application will have to execute something like this:

StatisticsService mBean = new StatisticsService();
SessionFactory sessionFactory = ...get hibernate session factory...
mBean.setSessionFactory(sessionFactory);
ObjectName objectName = new ObjectName("Hibernate:application=MY_APP_NAME,type=statistics");
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
mbs.registerMBean(mBean, objectName);
sessionFactory.getStatistics().setStatisticsEnabled(true);

Once you place your statistics MBean in an MBeanServer that can be remotely accessed, your Jopr Hibernate plugin will do the rest.

4 comments:

  1. Very nice!

    Anything we can do to avoid the requirement for users to manually add those external dependencies ?

    ReplyDelete
  2. Max - yes, it would be nice if there were some Hibernate configuration settings that enabled this, just as you can enable/disable second-level-cache for example.

    Example:

    hibernate.statistics.enabled=true
    hibernate.statistics.mbeanserver=*platform*

    This would turn on Hibernate statistics and tell it to register the Statistics MBean in the JVM's platform MBean Server (ManagementFactory.getPlatformMBeanServer). Of course, *platform* would only be valid on Java5 or higher VMs.

    Or...

    hibernate.statistics.enabled=true
    hibernate.statistics.mbeanserver=my_mbs_name

    This tells Hibernate to register the MBean in the named MBeanServer where the "name" is the default domain name of the MBeanServer you want (if it doesn't exist, Hibernate should create the MBeanServer with the named default domain).

    In fact, I had the Remoting project do something similar, so you can see code that gets the MBeanServer using these two ways by looking at the .patch attached to: https://jira.jboss.org/jira/browse/JBREM-746

    ReplyDelete
  3. Hi Mazz!
    To complement your post.
    I test Hibernate Statistics on Jboss applications by creating a MBean xxx-service.xml and put it in deploy directory without need change the code of my components deployed on server. In other words at run time...

    I think that's important when we don't want change old code.

    The MBean XML code for HibernatStatistics like this:

    [server]
    [mbean code="org.hibernate.jmx.StatisticsService"
    name="Hibernate:application=APP_NAME,type=statistics"]
    [attribute name="SessionFactoryJNDIName"]HibernateSessionFactory_NAME[/attribute]
    [attribute name="StatisticsEnabled"]true[/attribute]
    [depends]jboss:service=Naming[/depends]
    [/mbean]
    [/server]


    NOTE: the Hibernate Factory name need exists in JNDI.

    ReplyDelete