The following considerations should be reviewed prior to working with the System Manager Listener API.
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:
lookupObjectType
operations are performed only once. Thereafter,
the Event and Accumulator
objects that are returned are used directly, and therefore, execute as efficiently
as possible.accumOperationOne.recordValue(5000);
Duration anotherDuration = listener.durationFactory(accumOperationOne);
anotherDuration.start();
-
application code execution -
anotherDuration.stop(true);
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.
Server application implementations often include a dispatch table, or some similar central location in the code where client requests are handled. Developers are recommended to add the top-level System Manager instrumentation code at a location similar to this within their application structure. Frequently, only a few lines of code will need to be added to enable a basic level of performance monitoring.
The System Manager 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.
CAUTION The System Manager 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 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:
The following examples demonstrate some possible implementations for gathering performance data.
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();
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);