Using the Sample Plug-in

The sample plug-in, payme-insight-plugin, makes it easy for a developer to add new instrumentation for a specific technology such as Hibernate or Struts. The sample does not provide an example for creating an End Point, although other plug-ins within the Developer Kit show how this can be accomplished.

The sample demonstrates how to extract details from calls within a target application. In this case, the plug-in intercepts all calls to .setBalance(int) on any object. This capability is useful when you have many different Web applications, with different domains (credit card accounts, investment accounts) that you want to monitor. As long as the Web application calls .setBalance(int), the balance that is set will be recorded by Spring Insight, with no need to change code in any Web application.

Sample Plug-in Files

The files included with the sample represent most of the files a typical plug-in needs. Each file contains more detailed documentation.

src/main/java/org/myorg/insight/myplugin/CashMoneyOperation.java
src/main/java/org/myorg/insight/myplugin/CashMoneyOperationCollectionAspect.aj
src/main/resources/META-INF/insight-plugin-myplugin.xml
src/main/resources/org/myorg/insight/myplugin/cash_money_operation.ftl

CashMoneyOperation.java

The CashMoneyOperation.java file represents what happens when setBalance() is called on an object. The CashMoneyOperationCollectionAspect captures the argument to setBalance() and populates the CashMoneyOperation with this data.

It is the plug-in's own implementation of Operation that holds information captured by the aspect. When the aspect intercepts a call to setBalance(30), for example, it takes the 30 and creates a new CashMoneyOperation with that information. Implementations of Operation primarily act as simple beans.

CashMoneyOperationCollectionAspect.aj

The aspect that intercepts calls to setBalance() and creates new CashMoneyOperations. For more details, see Collecting Runtime Data.

insight-plugin-myplugin.xml

The insight-plugin-myplugin.xml file is the plug-in descriptor, a Spring application context file that is packaged with the plug-in. Spring Insight uses this file to locate and initialize the plug-in and to learn how the UI should render the plug-in's specific data.

The file contains a plain Spring XML beans definition. The file is included in the plug-in JAR and must follow this pattern: /META-INF/insight-plugin-pluginname.xml. The most common beans to define are EndPointAnalyzers and custom views for operations. See EndPointAnalyzer.

cash_money_operation.ftl

The FreeMarker template that is rendered when the CashMoneyOperation is displayed in the Spring Insight dashboard. The template is populated with a binding for Operation onto an instance of CashMoneyOperation. See Operation Rendering in the UI.

The filename (cash_money_operation.ftl) is looked up via the insight-plugin-myplugin.xml configuration file.

Collecting Runtime Data

Spring Insight gathers data from a running Web application primarily through the use of Aspect Oriented Programming (AOP). AspectJ is an Open Source AOP technology that allows Spring Insight to capture data without any changes to the user's code.

Plug-ins can define their own aspects, which will be woven into the target application at runtime. Plug-ins also define their own Operation subclasses that can be instantiated by the aspects. These plug-in operations are then moved through the Spring Insight repository for storage and later viewing.

The sample plug-in uses aspects to intercept calls to methods called setBalance().

See CashMoneyOperationCollectionAspect.aj.

Operation Rendering in the UI

If a plug-in creates its own Operation, it should also create a view to render it in the UI. Plug-ins can define a Spring View with which to render their Operation into HTML. FreeMarker is the recommended view technology. You can use other view technology if it implements the Spring View interface. However, the libraries needed to render the view must already be available. JSP is not an option because the files live outside the servlet environment.

When rendering a trace in the UI, the Spring Insight dashboard examines the OperationType of each Operation in the trace. It uses this type to locate an associated view. If a plug-in defines the view, the Spring Insight dashboard renders it and includes the generated content in the response.

For operations that do not define a view, a generic view attempts to display all the properties of the Operation. Although the generic view is useful while you are developing a plug-in, we do not recommend shipping a plug-in that depends on this view.

Inside the plug-in's Spring context, you register a view as follows:

<bean id="operation.cash_money_operation"
      class="org.springframework.web.servlet.view.freemarker.FreeMarkerView">
    <property name="url" value="org/myorg/insight/myplugin/cash_money_operation.ftl"/>
</bean>

The bean ID must take the form "operation.operationTypeIdentifier". The URL property is the path to the FreeMarker template from the root of the JAR.

The rendered HTML should be clean, balanced, and semantic.

<h2>Operation Title</h2>
<table class="dl">
  <tr>
    <td>Name1</td>
    <td>Value1</td>
  </tr>
  <tr>
    <td>Name2</td>
    <td>Value2</td>
  </tr>
  ...
</table>

The Spring Insight Dashboard web application includes a FreeMarker macro file you can use to ensure your operation is rendered in a consistent way. The above HTML can be written this way:

<#ftl strip_whitespace="true">
<#import "/insight-1.0.ftl" as insight />

<@insight.group label="Operation Title" >
    <@insight.entry name="Name1" value=operation.Property1 />
    <@insight.entry name="Name2" value=operation.Property2 />
</@insight.group>

In the example, Property1 and Property2 are properties with getters in the Operation class. The value of the name attribute is printed in the first table column and the value returned by the getter (value attribute) is rendered in the second column. See the core plug-in source code for more examples.

EndPointAnalyzer

Plug-ins can hook into the Analyze End Points phase of Spring Insight, allowing them to define their own concept of what constitutes an End Point. An EndPointAnalyzer looks at a trace and says, "This is a Servlet End Point at /imageServlet" or "This is a Controller End Point at BankController#debitAccount."

Most plug-ins do not need to implement this functionality. It is most useful for dispatching frameworks such as MVC, JMS, and Servlets.

All registered EndPointAnalyzers can look at each trace as it is created and determine which End Points it has. Because many plug-ins run per trace and each one can produce its own EndPointAnalysis, only a single EndPointAnalysis will represent the trace. It is determined by the score field within EndPointAnalysis.

To create a new EndPointAnalyzer, create a class that implements EndPointAnalyzer and expose the class to Spring Insight by adding it to the plug-in's Spring context file (insight-plugin-myplugin.xml).

The following diagram shows plug-ins creating End Point analysis based on trace examination.