The other day while commuting from home to work, I discovered the Spring Insight project. From what I've seen so far Spring Insight is a set of inspections (plugins) which are visually displayed in a web application. To get an idea of what Spring Insight can do for you, be sure to check out the introduction screencast.
By default Spring Insight comes with a default set of plugins/inspections for different kinds of frameworks/libraries like:
- Spring Web, Spring core
- JDBC
- Servlets
- Hibernate
- Grails
- The amount of time taken for each processing phase of an HST component
- The time it takes to perform an HstQuery to the repository
Getting started
For this post we will now focus on creating an inspection on performing HST queries. From the Insight web application view I would like to see the information of an HstQuery and time it took to perform the actual query.
With AspectJ you can pick a join point and inspect for instance the execution of that join point. In our case I would like to inspect the HstQuery.execute() method. By putting the join point on the HstQuery interface, we've made sure that any object extending the HstQuery will be able to represent it's data within the Insight web application.
Let's first take a look at the what such an inspection looks like.
package com.jeroenreijn.insight.hst;
import com.springsource.insight.collection.AbstractOperationCollectionAspect;
import com.springsource.insight.intercept.operation.Operation;
import com.springsource.insight.intercept.operation.OperationType;
import org.aspectj.lang.JoinPoint;
import org.hippoecm.hst.content.beans.query.HstQuery;
import org.hippoecm.hst.content.beans.query.HstQueryResult;
import org.hippoecm.hst.content.beans.query.exceptions.QueryException;
/**
* Aspect for collecting HstQuery executions.
*/
public aspect HstQueryOperationAspect extends AbstractOperationCollectionAspect {
private static final OperationType TYPE = OperationType.valueOf("query_execute");
public pointcut collectionPoint(): execution(HstQueryResult HstQuery.execute());
public Operation createOperation(JoinPoint jp) {
HstQuery query = (HstQuery) jp.getTarget();
Operation op = new Operation()
.type(TYPE)
.label("HstQuery");
op.sourceCodeLocation(getSourceCodeLocation(jp));
try {
op.put("query", query.getQueryAsString(false));
op.put("limit", query.getLimit());
op.put("offset", query.getOffset());
} catch (QueryException e) {
// ignore for now
}
return op;
}
}
The more important part of the above collection aspect is the collectionPoint poincut, where we define what kind of operation we would like to collect information from. In this case we define an inspection on the HstQuery.execute() method.
Next to the collection point you will also see the createOperation() method. which allows you to collect certain information from the current state of the collection point. In the above code snippet we collect the actually HstQuery object and get some information from it like the actual JCR XPath query, the limit set on the query and the offset. That's all for the information collection part of our plugin.
Now that we've created the aspect for the HstQuery, let's create a view for this inspection. You can create a freemarker template for each inspection if you want. For the HstQuery I've created the following template.
<#ftl strip_whitespace=true>
<#import "/insight-1.0.ftl" as insight />
<@insight.group label="HST Query">
<@insight.entry name="Query" value=operation.query />
<@insight.entry name="Limit" value=operation.limit />
<@insight.entry name="Offset" value=operation.offset/>
</@insight.group>
In the above template we define the values that we've put as attributes on our Operation object. All we have to do now is wire the operation and the view together inside the plugin configuration.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:insight="http://www.springframework.org/schema/insight-idk"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/insight-idk http://www.springframework.org/schema/insight-idk/insight-idk-1.0.xsd">
<insight:plugin name="hst" version="${project.version}" publisher="Jeroen Reijn" />
<insight:operation-view operation="query_execute" template="com/jeroenreijn/insight/hst/query.ftl" />
<insight:operation-group group="Hippo" operation="query_execute" />
</beans>
So now that we've finished our plugin, we package it and drop it inside the collection-plugins folder of our Spring Insight instance. Next we fire up the VMware vFabric TM tc Server and do some requests on the web application that we would like to get some information from. Once that's done switch the URL in the browser to '/insight' and there is the information collected by Spring Insight. The image below show exactly the information that we tried to show.
The advantage of having such a plugin might help us identify some slow pages that might have slow JCR queries or components that do extensive (unnecessary) processing.
Summary
Spring Insight is a very interesting project. Doing a quick scan for troublesome code is relatively fast, but can for now only be done with the VMware vFabric TM tc Server, so you cannot run it in your personal preferred application container like Tomcat, Jetty or JBoss. I've personally added Spring Insight to my default set of tools for figuring out performance issues when I need to do a review of a project.
All of the above code and how to install this HST Spring Insight plugin can be found on the plugin project page on Github.











I came across the term 'semantic web' a couple of years ago, when 