Implementation Considerations
The following considerations should be reviewed prior to working with the System Manager Listener API.
- Use of Global Variables
- Use of Duration Class
- Location of System Manager Listener API Calls
- Performance Data to Record
- Examples
Use of Global Variables
Each application must create exactly one Listener object, which must exist for the lifetime of the program. Therefore, the usual implementation strategy will consist of static member variables of a class to create the equivalent of global variables. For example, an application might specify the following declarations:
static Listener listener = new Listener("appName", "4.0");
static Event operationOne = listener.lookupEvent(PCHeventClass.RPC, "operation one");
static Accumulator accumOperationOne = operationOne.lookupAccumulator("duration of operation one");The advantages of this approach include the following:
- The
lookupObjectTypeoperations are performed only once. Thereafter, the Event and Accumulator objects that are returned are used directly, and therefore, execute as efficiently as possible. - The Events and Accumulators may be easily accessed from any part
of the code by making calls similar to the following:
accumOperationOne.recordValue(5000); Duration anotherDuration = listener.durationFactory(accumOperationOne); anotherDuration.start(); -application code execution- anotherDuration.stop(true);
Use of Duration Class
Since Duration objects can be reused (start may be called again after stop has been called), the application may choose to keep these objects in data structures associated with each thread that processes client requests.
Location of System Manager Listener API Calls
Server application implementations often include a dispatch table, or some similar central location in the code where client requests are handled. Add the top-level System Manager API instrumentation code at a location similar to this within your application structure. Frequently, only a few lines of code will need to be added to enable a basic level of performance monitoring.
Performance Data to Record
IBM® System Dashboard for Enterprise Content Management is intended to be used to monitor the overall health and operation of an application, and to yield a small enough impact on performance that it may be easily deployed in the field. Generally, this requires counting and timing high-level operations in the application, such as the number of times each different RPC call is made to a server, how long it took the server to respond to these calls, and what other resources were required to formulate that response.
When implementing support for performance monitoring, consider whether to record the following:
- Calls from Clients
- At a minimum, a server application should use Events to record each call that it receives from a client that it services, as well as the amount of time it takes to process the request. Frequently, other information related to the servicing of the call should be recorded as well, such as the amount of disk I/O (amount of data read or written, or the number of reads and writes), the number of database queries, and so on. This additional data may easily be recorded using Accumulators associated with the Event representing each client operation.
- Operation Failures
- When it is possible that operations performed by the application may fail, then the application should record the number of operation failures. The recommended method is to define Accumulators to count the failures, as their use would enable a Manager to automatically compute the failure rate.
- Small Durations
- Do not attempt to use the System Manager Listener API to measure Durations of many different, small sections of an application.
- Custom Messages
- Do not attempt to use the Custom Message facility as a replacement for general-purpose logging. The use of Custom Messages should be restricted to messages related to the performance aspects of the application, or for custom communication with Managers.
Examples
The following examples demonstrate some possible implementations for gathering performance data.
Cache Statistics
The following code fragment demonstrates how to define Events and Accumulators to record statistics on the behavior of a cache, such as the hit and miss ratios and the amount of I/O performed by the cache:
Listener listener = new Listener("appName", "4.0");
Event cache = listener.lookupEvent(PCHeventClass.USER, "cache", true);
Accumulator hits = cache.lookupAccumulator("hits");
Accumulator reads = cache.lookupAccumulator("reads");
Accumulator writes = cache.lookupAccumulator("writes");The following pseudocode demonstrates how to use the recordValue and recordEvent methods to gather the results of cache activity:
if (dataIsInCache) {
hits.recordValue(1);
} else {
if (have to write dirty entries to make room) {
writes.recordValue(pagesWritten);
}
// Read the data into the cache
. . .
// Record the cache activity
reads.recordValue(pagesRead);
}
cache.recordEvent();Object Store Statistics
The following code fragment demonstrates how to define a Container with subordinate Events and Meters to record performance data for an object store:
Container store = listener.lookupContainer("storeName");
Event creations = store.lookupEvent(PCHeventClass.RPC, "document creations");
Meter cacheSize = store.lookupMeter("cache size");
. . .
creations.recordEvent();
cacheSize.setValue(CacheSizeInMB);