Implementation Considerations
Review the following considerations before you start working with the System Manager Listener API.
- Use of Global Variables
- Use of Duration Objects
- 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 consists of global variables or static member variables of a class. For example, an application might specify the following global declarations:
Listener *listener = new Listener("sampleApp", "4.0", NULL, false);
Event *operationOne = listener->lookupEvent(RPC, "operation one");
Accumulator *accumOperationOne = operationOne->lookupAccumulator("duration of operation one");The advantages of this approach include the following concepts:
- The
lookupoperations are implemented only one time. Thereafter, the Event and Accumulator objects that are returned are used directly, and therefore, run as efficiently as possible. - The Events and Accumulators can be easily accessed from any part
of the code by making calls such as:
accumOperationOne->recordValue(5); Duration anotherDuration(accumOperationOne); anotherDuration.start();- application code execution -anotherDuration.stop(true);
Use of Duration Objects
Since Duration objects can be reused, the application can choose to keep these objects in data structures associated with each thread that processes client requests, or the objects can be created on the stack as needed, as the cost of instantiating a Duration object is small. Note, start can be called again after stop is called.
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 the current one within your application structure. Frequently, only a few extra lines of code are needed to enable a basic level of performance monitoring.
Performance Data to Record
IBM® System Dashboard for Enterprise Content Management is not intended to be used as a code profiling library or as a replacement for a general-purpose logging facility. It 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 can be easily deployed in the field. Generally, this task 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 you are implementing support for performance monitoring, consider whether to record the following topics:
- Calls from Clients
At a minimum, a server application uses Events to record each call that it receives from a client that it services, along with the amount of time it takes to process the request. Frequently, other information that is related to the servicing of the call is recorded as well, such as the amount of disk I/O (amount of data that is read or written, or the number of reads and writes), the number of database queries. This additional data can easily be recorded by using Accumulators associated with the Event representing each client operation.
- Operation Failures
When it is possible that the operations carried out by the application might fail, then the application can record the number of operation failures. 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 regular logging. The use of Custom Messages can 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 carried out by the cache:
Listener listener("sampleApp", "4.0", NULL, NULL); Event *cache = listener->lookupEvent(USER, "cache"); 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 member functions 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("document creations"); Meter *cacheSize = store->lookupMeter("cache size"); . . . creations->recordEvent(); cacheSize->setValue(CacheSizeInMB);