Skip to main content

IBM WebSphere Developer Technical Journal: Writing a Performance Monitoring Tool Using WebSphere Application Server's Performance Monitoring Infrastructure API

Srini Rangaswamy (sriniri@us.ibm.com), Advisory Engineer, IBM WebSphere Performance
Srini Rangaswamy is an advisory engineer at IBM. He is a member of the WebSphere performance group and is responsible for WebSphere Resource Analyzer. You can reach Srini at sriniri@us.ibm.com.
Ruth Willenborg (rewillen@us.ibm.com), Senior Engineer , IBM WebSphere Performance
Ruth Willenborg is a senior engineer at IBM. She has 15 years of experience in software development and is currently a member of the WebSphere development organization. Ruth is responsible for WebSphere's performance monitoring and performance benchmarking initiatives. You can reach Ruth at rewillen@us.ibm.com.
Wenjian Qiao (wenjian@us.ibm.com), Advisory Engineer, IBM WebSphere Performance
Wenjian Qiao is an advisory engineer at IBM. She is a member of the WebSphere performance group and is responsible for the design and implementation of WebSphere's Performance Monitoring Infrastructure. You can reach Wenjian at wenjian@us.ibm.com.

Summary:  This article discusses how to use the Performance Monitoring Infrastructure (PMI) API to write a performance monitoring tool for WebSphere Application Server. A sample command-line program developed using the PMI API is available for download with this article.

Date:  13 Feb 2002
Level:  Introductory
Activity:  776 views

Introduction

In today's complex e-business environment, customers need to be able to monitor different components of the entire production environment. WebSphere® Application Server, Version 4.0 lets you monitor run time and application components through its Performance Monitoring Infrastructure (PMI) API.

In this article, we will discuss how to use the PMI API to write a performance monitoring tool for WebSphere Application Server. A sample command-line program developed using the PMI API is available for download below. The PMI API documentation is also provided as a separate download.


Performance Monitoring Infrastructure API

The PMI API provides a framework to instrument WebSphere Application Server run-time and application components. The client side of this framework is externalized and published as a lightweight JavaTM API that allows you to gather performance data from the instrumental components. This client-side API is used by WebSphere Resource Analyzer and tool vendors; you can also use it to develop your own custom monitoring tool.

The PMI client uses RMI over IIOP to connect to WebSphere AdminServer. In addition, a performance servlet is provided to return performance data in XML format.

Figure 1 below shows the client-side view of PMI in WebSphere Application Server 4.0 Advanced Edition.


Figure 1. PMI client-side view
PMI client-side view

While the server side of the PMI API in each application server keeps the performance data as raw counter values, the client side retrieves and manipulates the raw counters to provide more meaningful values, such as average, time-weighted average, percentage, delta, and rate, etc. This minimizes the server overhead and allows the server data to be shared across multiple clients.

PMI API support in different WebSphere Application Server versions:

WebSphere Application Server Version/EditionPMI API support
WebSphere 4.0.2 Advanced Single ServerYes, via session bean
WebSphere 4.0.1 AdvancedYes
WebSphere 4.0 Advanced Single ServerNo
WebSphere 3.5.5 AdvancedYes, via 4.0.2 PMI client mapping

PMI Data Organization

The performance data from the PMI client is organized into modules. In WebSphere Application Server 4.0, PMI provides performance data about the following modules:

Run-time modules

  • Connection pool - Database connection pool
  • Thread pool - Web container and ORB thread pool
  • Session manager - HTTP Servlet sessions
  • Transaction manager - Transactions
  • JVM run time - Application server JVM
  • JVMPI - JVM Profiler Interface data
  • J2C - J2C connectors

Application modules

  • EJB module - EJBs and their methods
  • Web applications - Servlets and JSPsTM

A module can have sub-modules and each module/sub-module will have related performance data (that is, metric or counter). For instance, the Thread Pool module has two sub-modules: Web Container pool and ORB pool. Each of these sub-modules will have performance data, such as pool size, active threads, etc., and the parent Thread Pool module will aggregate the data from the sub-modules.


Figure 2. PMI Thread Pool module
PMI Thread Pool module

Each module has an associated instrumentation or monitoring level (Max, High, Medium, Low, None) that defines the data set for a given module. For the Thread Pool module,

  • None will disable all {}
  • Low will enable {Threads created, Threads destroyed}
  • High will enable {Threads created, Threads destroyed, Active threads, Pool size, Percent maxed}

The instrumentation level for each module can be set to a desired level (described in Step 2 below). Each metric in a module has a predefined level. A metric will be enabled if the module level is equal to or higher than its level. In the above example, the Pool Size is at level High and Threads created is at level Low.

Note: WebSphere Application Server nodes and servers are represented as modules without any performance data.


PMI classes

The client-side PMI classes are defined in the com.ibm.websphere.pmi package. The following are some of the core client-side classes that will be used in developing a custom monitoring tool. Refer to the PMI API documentation for detailed information about the following and other available classes.

ClassDescription
com.ibm.websphere.pmi.CpdCollectionRepresents a module or sub-module. For example, Thread Pool will be a CpdCollection object with two sub-collections: one for Web Container pool and another one for ORB pool.
com.ibm.websphere.pmi.CpdDataRepresents performance data. For example, Pool Size will be CpdData object available within Thread pool CpdCollection.
com.ibm.websphere.pmi.CpdValueRepresents the actual numeric value of the counter. CpdStat and CpdLoad are specialized CpdValue representing Average and Time-weighted average.
com.ibm.websphere.pmi.PerfDescriptorIdentifies a module (CpdCollection) or individual counter (CpdData). PerfDescriptor has Node, Server, Module and a fully qualified name.

For instance, the fully qualified name of Web container thread pool module can be:
{root/flow/DefaultServer/threadPoolModule/
Servlet.Engine.Transports}

  • flow - node name
  • DefaultServer - app server name
  • threadPoolModule - module name
  • Servlet.Engine.Transports - sub-module name (Web container pool)
com.ibm.websphere.pmi.PmiClientThis is the main client-side interface to the server side PMI and has methods to connect, query and get performance data from the WebSphere AdminServer.

Figure 3 below shows the relationship among the above classes.


Figure 3. PMI client-core classes
PMI client-core classes

A step-by-step look at using PMI

With this basic understanding of the core PMI client classes, let's look at the steps involved in gathering performance data.

Step 1: Identifying PMI modules

The first step is to connect to the WebSphere AdminServer and find out which nodes, application servers and modules are available for monitoring. The following code snippet will help you identify all of the above.

// Connect to WebSphere AdminServer running at hostName:900 
PmiClient pmiClient = new PmiClient ("hostName", 900); 
 
// Get Node PerfDescriptor 
PerfDescriptor[] nodePd = pmiClient.listNodes (); 
 
// Get first node name 
String nodeName = nodePd[0].getName(); 
 
// Get AppServer PerfDescriptor 
PerfDescriptor[] serverPd = pmiClient.listServers (nodeName); 
 
// Get all modules in first application server 
PerfDescriptor[] modulePd = pmiClient.listMembers(serverPd[0]);

Now, we have a PerfDescriptor for all of the modules in the first application server. The listMembers call can be recursively made to get the sub-modules, and so on.

This is just one way to navigate down to the modules. PMI provides a rich set of API and allows you to gather data in different ways depending on your application need. For instance, you can construct a PerfDescriptor and query the server if you know the PMI data hierarchy for the server.

Step 2: Setting instrumentation level

The next step is to enable the modules for monitoring (default setting is disabled). Each module has an instrumentation level (max, high, medium, low, or none) that determines the number of counters available for monitoring. This setting is stored and used by the application server and not by the PMI client. Therefore, this setting is common across all the clients and if one client changes the setting, it will affect all the other clients.

The instrumentation level can be set using the WebSphere Application Server Administrative Console or WebSphere Resource Analyzer. The following code illustrates how to get and set the instrumentation level using the PMI API.

The getInstrumentationLevel() returns the instrumentation level for all of the modules and sub-modules recursively in the given node and server.

// Get instrumentation level 
PerfLevelSpec[] level =  
  pmiClient.getInstrumentationLevel (nodeName, serverName); 
 
// Get module path 
String[] modulePath = level[i].getPath(); 
 
//ex: path for Thread pool module is {pmi, threadPoolModule} 
 
// Get level 
int instruLevel = level[i].getLevel(); 
 
// ex: levels defined in PmiConstants.java

Now, you can navigate this level array, change the level to the desired level, and call setInstrumentationLevel() to set the level.

// To set ThreadPool module and sub-modules to high 
boolean recursiveFlag = true; 
level[i].setLevel (PmiConstants.LEVEL_HIGH); 
pmiClient.setInstrumentationLevel  
  (nodeName, serverName, level, recursiveFlag);

Alternatively, to set the level for a known module or an individual module (without calling the getInstrumentationLevel() method), you can do the following:

PerfLevelSpec[] spec = new PerfLevelSpec [1]; 
String[] modulePath = new String[] {"threadPoolModule"} 
spec[0] = pmiClient.createPerfLevelSpec  
  (modulePath, PmiConstants.LEVEL_HIGH); 
pmiClient.setInstrumentationLevel  
  (nodeName, serverName, spec, recursiveFlag);

The changes made through setInstrumentationLevel will take effect immediately (without having to restart the server) and will be persistent.

Note that all levels may not be applicable to a given module. For instance, the JVM module has three counters and all three gets turned on when the level is set to Low. In this case, setting it to a level higher than Low will still give only these three counters. The Max level is used in an EJB module to turn on method-level monitoring.

The instrumentation level also represents the performance cost involved in collecting the data. PMI is designed to be a low cost framework, so it can be used in production monitoring. When tested in our labs, we found the following:

  • With all modules set to High: ~2% performance degradation
  • With all modules set to Max: ~5% performance degradation

Step 3: Collecting PMI data

Once the instrumentation level is set for a given module, getting the performance data is just a single method call. You can send one or multiple PerfDescriptors and get their corresponding CpdCollection objects as follows:

// Get all sub-modules recursively 
Boolean recursiveFlag = true; 
 
// Get performance data for ONE module 
CpdCollection col = pmiClient.get (modulePd[0], recursiveFlag); 
 
// Or, get performance data for ALL of the modules 
CpdCollection[] col = pmiClient.gets (modulePd, recursiveFlag);

Step 4: Navigating the performance data set (CpdCollection)

Now, let's navigate the CpdCollection to get individual performance data:

// Get the performance data set from a CpdCollection 
CpdData[] perfData = col.dataMembers(); 
 
// Get the sub-modules 
CpdCollection[] subPerfData = col.subcollections ();

As mentioned earlier, a PerfDescriptor identifies a CpdData. So, from the PerfDescriptor we can get the name of the data as follows:

perfData[0].getDescriptor().getName(); 
//e.g. threadPoolModule.threadCreates

or

perfData[0].getDescriptor().getFullName(); 
// e.g. root/flow/DefaultServer/threadPoolModule/ 
  threadPoolModule.threadCreates

Finally, let's get to the actual counter value itself:

// Get the counter value 
CpdValue value = perfData[0].getValue (); 
 
// Refer to Step 5 for the definition of returned double value 
double numOfThreadsCreated = value.getValue(); 
long timeInMillis = value.getTime();

The timeInMillis represents the time associated with the counter value.

Step 5: Determining performance data types

The counter value from CpdData can be one of the following three types:

TypeDescriptionClassMethods
NumericSimple numeric counter,for example, threads createdCpdValuegetValue() - returns numeric count
StatisticAverage value of the counter, for example, average response timeCpdStatgetValue() - returns mean

count() - returns number of samples

LoadTime-weighted average, for example, pool sizeCpdLoadgetValue() - returns current value

mean() - returns time-weighted average

The counter type can be determined as follows:

CpdValue value = perfData[0].getValue (); 
 
// Counter type 
int counterType = value.getType(); 
if (counterType == PmiConstants.TYPE_STAT) 
{ 
} 
else 
if (CounterType == PmiConstants.TYPE_LOAD) 
{ 
} 
else 
{ 
     // Numeric Type 
}

After finding the counter type, you can call the appropriate methods to get the counter value and their components, if any, such as mean, weight, etc.


An in-depth look at PMI features

So far, we have seen how to get the basic performance data from WebSphere Application Server using the PMI API. Now, let's take an in-depth look at some of the PMI features.

CpdCollection and CpdEvents

Each time we query PmiClient using a PerfDescriptor, we get a new CpdCollection object. Instead of dealing with a new CpdCollection object each time, we can update the existing one with the new collection as follows:

// Original collection 
CpdCollection orgCol = pmiClient.get (modulePd) 
 
// Updating the original collection with new collection 
orgCol.update (pmiClient.get (modulePd));

This is equivalent to establishing a base value and then updating the base with a new value. This model can be used to create a snapshot view (this is explained in the next feature item). By default, the update method updates all of the sub-collections recursively and will remove any collection (from the base) that is not present in the new collection. The default behavior can be altered by using the following methods:

update (CpdCollection newCol, Boolean keepOld); 
update (CpdCollection newCol, Boolean keepOld, Boolean, recursiveFlag);

Also, the update() on CpdCollection will generate events (CpdEvent) to indicate the changes made in the original collection, for example, new data, new sub-module, etc. By implementing the CpdEventListener interface, you can receive all of these events. This feature will be particularly useful when developing a GUI application using PMI. Note that the events can be sent only to listeners in the local JVM process.

Taking a performance snapshot

The application server keeps the cumulative raw counter value from the time it was started. The data in the client side can be reset to capture a snapshot view.

Here is an example to find the number of requests processed between the interval t2 and t3.

Let's assume the following sample data:

TimeServer value
(total req processed)
Client value
(without any reset)
Client value
(reset at t2)
t0000
t1100100100
t2180180180 resets to 0
t325025070
t4300300120

From the above sample data, the number of requests processed between the interval {t2 to t3} is 70 and {t2 and t4} is 120.

This can be computed programmatically by maintaining a base CpdCollection and updating it as described in the previous feature. For example, to count the number of requests between t2 and t3, call the reset() method on the CpdCollection (or the CpdData) at t2. At t3, get data from the server and update the base CpdCollection. Now, the data in the base collection will represent a snapshot from t2 to t3.

Static information about performance data

We have seen how to get the dynamic side (actual counter) of the performance data. The static information, such as counter name, description, level, etc., can be obtained from the PmiDataInfo class.

PmiDataInfo can be obtained in two ways, as shown below.

Getting PmiDataInfo from a CpdData instance:

// CpdData[] perfData; 
PmiDataInfo staticInfo = perfData[0].getPmiDataInfo (); 
staticInfo.getName(); 
staticInfo.getLevel (); 
staticInfo.getComment();

Getting PmiDataInfo from PmiModuleConfig:

// Get config for all modules 
PmiModuleConfig[] configs = PmiClient.getConfigs(); 
 
// Locate a module 
String modName = configs[0].getShortName (); // ex: "threadPoolModule" 
 
// List the dataset in the given module config 
PmiDataInfo[] staticInfo = configs[0].listAllData ();

Connecting remotely through a firewall

Since PmiClient uses RMI/IIOP to connect to the WebSphere AdminServer, you need to "poke a hole" in the firewall to connect to a server behind the firewall. Or, you can use the performance servlet to collect the data.

Using PMI with security

When the WebSphere Application Server security is turned ON, the user needs to be authenticated before calling any PMI API. You can configure the %WAS_HOME%\properties\sas.client.props to choose the appropriate login source.

Refer to the WebSphere 4.0 InfoCenter for details on different security configurations.


WebSphere Resource Analyzer and the performance servlet

WebSphere Resource Analyzer, a default PMI data viewer, is shipped with WebSphere Application Server 4.0 Advanced Edition. It uses PMI API and provides a simple GUI to monitor, record, and replay performance data.

The performance servlet (PerfServlet), a firewall-friendly PMI data viewer, is also shipped with WebSphere Application Server 4.0 Advanced Edition (%WAS_HOME%\installableApps\perfServletApp.ear). Install this EAR file in any one of the application servers in a node, and invoke it with this URL: http://localhost/wasPerfTool/servlet/perfservlet. PerfServlet provides performance data in the XML format.


WebSphere Statistic (wsstat): A sample program

The WebSphere Statistic tool is a command-line performance monitoring tool developed using PMI. When invoked, it lists all of the modules that are available for monitoring. It allows you to monitor one module at a time, with a given refresh interval and can record the data to a file, if required.

The source code is available here. Figure 4 below shows screen shot of the wsstat tool.


Figure 4. The WebSphere Statistic tool
The WebSphere Statistic tool

Conclusion

WebSphere PMI API lets you gather performance data from WebSphere Application Server. PMI API can be used to build custom tools to monitor WebSphere Application Server in the production environment.



Download

NameSizeDownload method
download.zip92 KBFTP|HTTP

Information about download methods


Resources

About the authors

Srini Rangaswamy is an advisory engineer at IBM. He is a member of the WebSphere performance group and is responsible for WebSphere Resource Analyzer. You can reach Srini at sriniri@us.ibm.com.

Ruth Willenborg is a senior engineer at IBM. She has 15 years of experience in software development and is currently a member of the WebSphere development organization. Ruth is responsible for WebSphere's performance monitoring and performance benchmarking initiatives. You can reach Ruth at rewillen@us.ibm.com.

Wenjian Qiao is an advisory engineer at IBM. She is a member of the WebSphere performance group and is responsible for the design and implementation of WebSphere's Performance Monitoring Infrastructure. You can reach Wenjian at wenjian@us.ibm.com.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=14214
ArticleTitle=IBM WebSphere Developer Technical Journal: Writing a Performance Monitoring Tool Using WebSphere Application Server's Performance Monitoring Infrastructure API
publish-date=02132002
author1-email=sriniri@us.ibm.com
author1-email-cc=
author2-email=rewillen@us.ibm.com
author2-email-cc=
author3-email=wenjian@us.ibm.com
author3-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers