Before anything can be reported, the application have to expose it's state to the monitoring infrastructure. In Commons Monitoring vocabulary this is called instrumentation of the application. Commons Monitoring defines a simple lightweight API for this purpose.
The application exposes it's state based on monitors . A monitor is an abstraction for any element in the application that can expose state or resource consumption. This can be a code fragment, a web application URI, a JDBC query, some business object data, etc. It is identified by :
Only the name is required, but category and subsystem is a nice way to group monitors by technical or functional criteria.
Monitors are registered in a repository, that ensure a monitor is unique for a name/category/subsytem Key. The repository is used to retrieve existing monitors and create new ones. The default repository implementation creates new Monitor instance when a non-existing one is requested, so you don't have to wory about monitors management.
Monitor monitor = repository.getMonitor( "MyService.myMethod" );
Monitor monitor = repository.getMonitor( "SoapEndpoint.process", "soap" );
Monitor monitor = repository.getMonitor( "/admin/userEdit.do", "struts", "user management" );
You can use a custom repository by extending one of the provided implementations. You can also
use the ConfigurableImplementationsRepository implementation, when you only want to configure
custom implementation classes for StopWatches and Monitors.
Monitors manage a set of StatValues that the application uses to expose state. The
monitor only identifies where the data comes from, and the statValues handle the monitored data.
There is two types of values that application can use, depending on the data to be exposed :
add() method
to expose how the counter must increment when some operation have proceeded.
incremenet() and decrement()
methods to expose the application state changes. The set() method can also be used to
force an initial value or to expose an absolute value when the application does not compute it's state
as a change from a previous value. Typically, a connectionManager component will use
increment/decrement to expose active connections, and a fileSystemMonitor will use
set to expose free space on disks.
In both cases, the statValues compute statistical information from what the application exposes, like min / max / mean and standard deviation, that in many case is more informative than the current value. Available statistical indicators are limited as a StatValue does not maintain all the individual elements as a serie but only aggregates, to avoid memory over-consumption.
The default monitor implementation will create the required Gauge/Counters implementation when a statValue is requested by the application.
A monitor can handle many statValues. StatValues are identified in a monitor by a role, that describes the data beeing computed. There is predefined roles for performances, concurrency monitoring and failures count, but any other relevant counter/gauge can be registered to a monitor.
final static Role BYTES = new Role( "bytes", Unit.BYTES, Counter.class );
static Monitor monitor = repository.getMonitor( "SoapEndpoint.process" );
static Counter bytes = monitor.getCounter( BYTES );
public void process( SOAPMessage message )
{
// Process a SOAP message
// retrieve the custom Counter for the "byte" role
bytes.add( SOAPMessage.getSize(), Unit.BYTES );
}
A role can be considered as a statValue prototype. It defines :
Counter.class or Gauge.classCounters and Gauge knows the data type they hold, based on the Role used to create them :
Any data set/addition is checked for unit to be compatible. "compatible" means the passed values can be
converted to the same primary unit, "primary" beeing the finest unit available for a data type.
For example, Unit.SECONDS, is compatible with Unit.MILLIS
as they share the same primary unit Unit.NANOS.
You can define your own units on the same basis, to ensure good usage of your monitors and cleaner reporting. You can also pass data to a statValue with any compatible Unit, as the statValue will internally handle any required conversion.
Performance monitoring is first-class use case of Commons Monitoring. The
org.apache.commons.monitoring.StopWatch class provides the necessary tooling
to compute and monitor code or service invocation performances. A StopWatch is created
by the repository for a monitor. The stopwatch is initialy "started", and will compute
elapsed time until it is stopped by the application. The application MUST ALLWAYS stop
the StopWatches it has created ! To ensure this, always use a finally block :
StopWatch stopWatch = repository.start( myMonitor );
try
{
// Do something that takes time and requires monitoring
}
finally
{
stopWatch.stop();
}
You can nest stopWatches, in many case by monitoring some high-level process (for example web request rendering time) and nested low-level service (remote service invocation, JDBC request...). The monitor maintains statistics about those informations as the PERFORMANCE and RESPONSE_TIME counters. First one only computes performance of the target code, not sub-processes.
The default StopWatch implementation
can be extended to support some custom features. ExecutionStopWatch for example adds support for
a list of all stopwatches beeing used in the current thread, so that you can trace the activity if you
detect bad performances of the global process. To use a custom StopWatch class, simply setup the
repository using new DefaultRepository( MyCustomStopWatch.class ).
The Monitoring class is a convenience utility class to make application instrumentation as simple as possible. To monitor application performance, simply do :
public void myMethodToGetMonitored()
{
StopWatch stopWatch = Monitoring.start( "MyClass.myMethod" );
try
{
// Do something that takes time and requires monitoring
}
finally
{
stopWatch.stop();
}
}
The StopWatch class will compute the time elapsed during code execution and report it to the
monitor "MyClass.myMethod".
Other helper classes are provided for simplier use with commons frameworks. The
org.apache.commons.monitoring.aop package contains for example classes for use with
AOP frameworks to automagically instrument application components.