Transaction monitoring technology from IBM allows web server operators and application developers to examine the performance details of individual transactions. A transaction starts when a user clicks a button on a browser and ends when the requested data is displayed on the browser page. During this processing, several - perhaps hundreds - of sub-transactions will be spawned to support the user's request. Without the ability to examine the performance of individual sub-transactions, identifying and correcting performance problems becomes extremely difficult. By using the ARM 4.0 api along with the IBM Tivoli Monitor for Transaction Performance 5.3 (ITMTP 5.3), we can get a clear understanding on how our web server's transaction processing is affecting the ability to serve customers at the desired level of performance. The programming examples are compatible with the IBM Tivoli Composite Application Manager for Response Time Tracking (ITCAMfRTT) as well. This article assumes that you already have ITMTP 5.3 or ITCAMfRTT 6.0 installed along with the IBM Http Server and you are ready to start managing your web transactions.
Application Response-time Measurement, or ARM, is a programming interface that allows application writers to define the business logic of an application in terms of individual transactions. ARM models the transaction in three basic steps. The first step, is to define the nature of the transaction; second, start the transaction and lastly, stop the transaction. Determining how this three-step transaction model overlays the business logic should be the first design consideration when considering ARM instrumentation.
ITMTP 5.3 has the capability to discover when an application is making calls to the ARM interface. Once discovered, ITMTP will monitor the transactions defined by the application's business logic. Refer to the Resources at the end of this article for more information.
Hooking into Apache 2.0 Architecture
The IBM Http Server (IHS) is expandable through plug-in modules written with the Apache Portable Runtime (APR) library. This article is targeted toward the Windows™ platform, but the Portable in APR means that the same concepts and code presented here can be applied to any of the platforms supported by the library. You can link to the APR web site from the Resources section at the end of this article.
The APR provides hooks for processing the http requests coming into our server. Each hook occurs during a specific time during the processing of the request and carries certain information specific to the request being processed. Before we begin to define the business logic for our application, we must first understand how our application is going to process the transactions.
This section defines a sample module that will be used throughout the remainder of the article. In order to compile the source code you must first install the Apache Portable Runtime libraries and the ARM 4.0 libraries which are available when you install ITMTP 5.3.
The anatomy of an Apache 2.0 modular architecture is shown in Figure 1. The Apache Runtime will call the registered hooks of each of the loaded modules in a pre-determined order for each request that is processed by the server.
Figure 1. Apache 2.0 Module Architecture
Once each module has had an opportunity to process the in-coming request, the server processes the final request and generates the requested page content. After the content has been generated, the Apache Runtime calls the registered output filters and cleanup routines of each loaded module.
Figure 2. shows the hooks that our sample module will be implementing. Figure 2. also gives us an idea for how to define the business logic for modeling the transactions. In other words, once we understand how our application is going to handle the transactions it is simple to determine when to define, start and stop the transactions using the ARM api. For this example, out enterprise server will be hosting a web site that allows customers to view a picture of items from an on-line catalog. The pictures are GIF files that are stored in a database on a separate image server. Therefore, we have defined a transaction called Gif Request and we wish to monitor how long it takes the images server to process these transactions.
Figure 2. The sample module.
Listing 1. The sample module.
#include "ap_config.h"
#include "httpd.h"
#include "http_config.h"
#include "http_core.h"
#include "http_request.h"
module AP_MODULE_DECLARE_DATA sample_module;
static int sample_fixup(request_rec *r)
{
ap_add_output_filter("SAMPLE", (void *)NULL, r, r->connection);
return DECLINED;
}
static apr_status_t out_filter(ap_filter_t *f, apr_bucket_brigade *b)
{
ap_pass_brigade(f->next, b) ;
return APR_SUCCESS;
}
static int initializeApp(apr_pool_t *pool, server_rec *s)
{
return OK;
}
static void register_hooks(apr_pool_t *p)
{
ap_hook_child_init(initializeApp,NULL,NULL,APR_HOOK_MIDDLE);
ap_hook_fixups(sample_fixup, NULL, NULL, APR_HOOK_LAST);
ap_register_output_filter("SAMPLE",out_filter,NULL,AP_FTYPE_RESOURCE);
}
module AP_MODULE_DECLARE_DATA sample_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create directory config */
NULL, /* merge directory config */
NULL, /* create server config */
NULL, /* merge server config */
NULL, /* command apr_table_t */
register_hooks /* register hooks */
};
|
In order to get started we first need to get the environment ready to run our application. The central feature of the environment is the IBM Http Server. This is the server that will run the instrumented plug-in module. It is important to install IHS version 2.0 or later. Once the IHS is installed, the sample module needs to be loaded. Even though the module does not do any thing at the moment it is a good idea to make sure that it is running properly before continuing.
A Makefile for building the module and the source code are available
for download. Assuming you have been able to successfully build the
sample module, you should have a relocatable library called
mod_sample.dll if you are using Windows™ or mod_sample.so if
your IHS is on Linux. The mod_sample.dll file needs to be copied to
the modules directory under the IHS installation. Next,
modify the file httpd.conf as shown below.
Listing 2. Changes to httpd.conf
LoadModule sample_module modules/mod_sample.dll |
Prepare Http Server for Transaction Monitoring
The final step in getting the environment ready is to install the ITMTP 5.3 management agent onto the machine running the IHS web server. The management agent provides an ARM engine that allows instrumented applications to record transaction data. Once the agent has been installed, no further configuration is necessary. After the instrumented application is in place, we will allow ITMTP 5.3 to automatically provide the necessary configuration to start monitoring our web server.
Figure 2 above shows how our module is going to interact with our transaction processing. From this it is easy to see where we need to add the ARM instrumentation. The first step is to define our application and describe the transactions we will be monitoring.
The init_child hook is called each time the Apache Runtime starts a new thread to process an incoming request. This is where we will place the ARM calls to register and start the application. Since our web module is multi-threaded we can potentially have several instances of the application running at the same time. The ARM engine needs to keep track of which transactions are associated with which application instance (or thread). Therefore, when the application is started, we provide a process identifier for each application instance.
We need to make the following changes to the sample module.
Listing 3. Register and Start the Application.
typedef struct server_config {
arm_id_t _appId;
arm_id_t _tranId;
arm_app_start_handle_t _aHndl;
int test;
} server_config_t;
static void *create_server_config(apr_pool_t *p, server_rec *s)
{
return (server_config_t *) apr_pcalloc(p, sizeof(server_config_t));
}
static int initializeApp(apr_pool_t *pool, server_rec *s)
{
arm_error_t rc;
server_config_t *sconf;
char *pid_str;
const char appName[] = "My First Sample App";
sconf = ap_get_module_config(s->module_config, &sample_module) ;
arm_register_application(appName,
ARM_ID_NONE,
ARM_FLAG_NONE,
NULL,
&(sconf->_appId));
arm_register_transaction(&(sconf->_appId),
"GIF Request",
ARM_ID_NONE,
ARM_FLAG_NONE,
NULL,
&(sconf->_tranId));
pid_str = apr_itoa(pool, getpid()) ;
rc = arm_start_application(&(sconf->_appId),
s->server_hostname,
pid_str,
ARM_FLAG_NONE,
ARM_BUF4_NONE,
&(sconf->_aHndl));
return OK;
}
module AP_MODULE_DECLARE_DATA sample_module =
{
STANDARD20_MODULE_STUFF,
NULL, /* create directory config */
NULL, /* merge directory config */
create_server_config, /* create server config */
NULL, /* merge server config */
NULL, /* command apr_table_t */
register_hooks /* register hooks */
};
|
Listing 3 adds the create_server_config function. This
allows each application instance to maintain a unique copy of the application
identifier and handle used by the ARM engine.
The next step in defining the transaction model is to start an instance
of the GIF Request transaction that we registered above. Since the
fixup hook is called immediately before the request is sent to the
web server for processing this is an ideal location to start the transaction.
In order to insure that we start the transaction as close to the start of
the transaction processing we can tell the Apache Runtime to call this hook
at the last possible moment.
ap_hook_fixups(sample_fixup, NULL, NULL, APR_HOOK_LAST)
Listing 4. shows how the sample_fixup is modified to perform the ARM api call to start
a transaction. We have also added a data structure to keep track of the transaction
handle. By passing a reference to this data
structure to ap_add_output_filter we can retrieve the data once the callback
is performed on the output filter.
Listing 4. Starting the Transaction
typedef struct sample {
char * uri;
arm_tran_start_handle_t _tHndl;
arm_id_t _tran_id;
} sample_ctx;
static int sample_fixup(request_rec *r)
{
int rc;
sample_ctx * ctx;
server_config_t *sconf;
sconf = ap_get_module_config(r->server->module_config, &sample_module);
ctx = (sample_ctx *) apr_pcalloc(r->pool, sizeof(sample_ctx));
ctx->uri = r->uri;
arm_start_transaction(sconf->_aHndl,
&(sconf->_tranId),
NULL,
ARM_FLAG_NONE,
NULL,
&(ctx->_tHndl),
NULL
);
ap_add_output_filter("SAMPLE", (void *)ctx, r, r->connection);
return DECLINED;
}
|
Finally, when the server has completed the transaction processing the Apache runtime will call our output filter as shown in Figure 2. above. This is where we will mark the end of the transaction GIF Request.
Listing 5 shows the calls to the ARM api to signify the end of the transaction.
Listing 5. Stopping the Transaction
static apr_status_t out_filter(ap_filter_t *f, apr_bucket_brigade *b)
{
sample_ctx *ctx = f->ctx;
if (ctx != NULL) {
arm_stop_transaction(ctx->_tHndl,
(f->r->status == 200?ARM_STATUS_GOOD:ARM_STATUS_FAIL)
ARM_FLAG_NONE,
NULL
);
f->ctx = NULL;
}
ap_pass_brigade(f->next, b) ;
return APR_SUCCESS;
}
|
Since it is possible for the output filter to be called more then once for a given transaction, the context data is set to NULL when the transaction has been stopped. This will prevent the transaction from being stopped more then once.
We are now ready to compile and test the module. A full listing of the sample module can be found in the downloaded source code. Compile the code and replace the mod_sample.dll with the new version. The IHS server may need to be stopped before the module can be replaced. Restart IHS, and browse to the server home page from any web browser. If the server's home page is successfully into the browser window then all is well and we are ready to start monitoring the transactions.
As mentioned above, ITMTP 5.3 has the ability to automatically discover ARM 4.0 instrumented applications along with any transactions they generate. First, we need to active the discovery on the agent. To do this, log into the ITMTP 5.3 management server console and from the left hand panel select Work with Discovery Policies
Figure 3. Work with Discovery Policies
On the Configure ARM Discovery panel, specify .* for the Application Name,
Transaction Pattern and User Name. For Sample Rate specify 100 percent. Select Next and
choose or create a schedule that starts now and runs continuously.
On the Agent Group panel, click the Create New button and select the agent which contains the http server which is being monitored and click Apply. Click Next again and enter ARM4 Discovery as the name of the policy. Click Finish. This should save the policy on the agent and activate the discovery of ARM transactions. The next thing to do is to create some transaction data.
Point another browser window to the home page of the http server. Make sure that the page is not retrieved from the browser cache.
Figure 4. IHS Home Page
Now return to the ITMTP 5.3 console and once again select Work with Discovery Policies. This time, you should see the ARM4 Discovery policy in the list. Select the policy and Choose View Discovered Transactions from the drop down list.
Figure 5. View Discovered Transactions
If the application list is empty, click the manual data roll-up button.
. The panel should contain a list of the discovered
ARM-instrumented applications including our sample module called My First Sample App.
This is the appName which was provided when we registered the application (see Listing 3).
Now that we have used ITMTP 5.3 to discover what transactions are
running on the http server we can configure a policy that will listen
for similar transactions in the future. select the application called
My First Sample App and choose Create Listening Policy
from from the drop down list.
Figure 6. Create the Listening Policy
This will bring you to the panel for configuring your listening policy for managing the
transactions. The values will be filled in based on the transactions that were
previously discovered. Some of these values are appropriate for our needs but others
need to change. Notably, the application instance; if you refer to Listing 3. above, you
may recall that the application instance was the process identifier of the server instance.
Clearly, we do not want our transactions to necessarily match this value since it will
change each time we invoke our module. Therefore, change the Application Instance to
the regular expression .*. The other values can remain the same.
Figure 7a. Configure the Listening Policy
Next, change the sample rate to 100 percent, meaning that we will record all transactions. And finally select the Aggregate and Instance Data radio button. This will provide us with details on each transaction record.
Figure 7b. Configure the Listening Policy (cont)
Be sure to select the same Agent Group that the discovery policy was save on, otherwise the application group will not match our policy definition. Once you navigate through the remaining panels, Assign a name to the policy and select Finish. This will save the listening policy on the agent. To start monitoring the transactions you must first disable the transaction discovery by returning to Work with Discovery Policies and disabling (or deleting) the policy called ARM4 Discovery.
Figure 8. Assign Policy Name
At this point we can start generating real transactions. Return the browser window pointing to your IHS home page and Refresh the content again being sure that the browser does not read from its local cache.
All that is left to do is to watch the data start rolling into the ITMTP server. From the left-hand panel expand the Reports tab and select View Dashboard
Figure 9. Dashboard - Policy Group
Click on the name of the policy group, in this case ARM Policies. This will show an overview of the current status of the policy. Currently the status is Normal. To cause a failure, browse to a page on the server that does not exist. Refer back to Listing 4. regarding how the business logic was defined for this transaction.
Listing 6. Defining the business logic
arm_stop_transaction(ctx->_tHndl,
(f->r->status == 200?ARM_STATUS_GOOD:ARM_STATUS_FAIL)
ARM_FLAG_NONE,
NULL
);
|
In the sample, any http return status other then 200 denotes a failed transaction.
Figure 10. Dashboard - Policy
Finally, click the topology icon
next to the policy name. From the
topology view we can see how the transaction fits into the overall transaction model. In
this case there is only one transaction and one application so it is rather un-interesting.
In the next section we will enhance the sample module application to use ARM correlators
to associate transaction with the overall business model we are implementing.
Figure 11. Topology
In this article we saw how to implement a simple IHS plug-in that started and stopped a transaction based on a certain request on the web server. In addition, we got to see how this transaction can be discovered and subsequently managed from ITMTP 5.3. The next steps will be to add additional business logic to the transaction definition with the use of ARM 4.0 metrics and tie in the transaction with the rest of our business model by using ARM correlators and ARM metrics. Refer to the Resources section below for more reading on these topics.
Although this sample module demonstrates how to implement manageable transactions on the web server, there is currently not enough information about the transaction to provide meaningful monitoring capabilities. For example, being able to discern the name of the file being requested. The next column will show how the use of metrics in the ARMv4 libraries can provide the necessary information for more comprehensive application management. In addition, we will see how to use ARM correlators to track the entire transaction from the initial request, through the web server and back to final rendering of data on the user's browser.
| Description | Name | Size | Download method |
|---|---|---|---|
| Complete code listings of sample module | dw_armplugins.zip | 11.5KB | HTTP |
Information about download methods
-
Connecting middleware to Apache 2.0
-
See developerWorks article for
BPEL Tracking for Transaction Monitoring for Transaction Performance
-
For additional information on ITMTP uses ARM technology, see
Architecting on demand solutions, Part 10: Monitor business IT services using IBM Tivoli Monitoring for Transaction Performance
-
Browse documentation for ITMTP.
-
For more information about ARM goto
The Open Group web site.
-
For more information about about the APR library and to download
latest version, visit the
Apache Portable Runtime web site.
-
To learn more about how Tivoli products, visit the developerWorks Tivoli
zone. You'll find technical documentation, how-to articles,
education, downloads, product information, and more.
-
Get involved in the developerWorks community by participating in
developerWorks
blogs.
Holds MS in Computer Science Engineering and 20 years experience in application development for business systems and real-time computing. Has spent seven years with IBM Tivoli software testing and development organization. Most recently writing software automation for the validation of Tivoli's composite application management products.




