Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Application Management for Web Servers: Developing an ARM-Managed Web Server Plug-in

Manage web server plug-ins with IBM Tivoli transaction performance products

Dan Mullen (mullenda@us.ibm.com), Software Engineer, IBM
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.

Summary:  Learn how to add your own custom transaction management capabilities to HTTP server plug-in modules for IHS®. By using the Application Response Measurement (ARM) libraries you will learn how to instrument an IHS module in order to monitor usage and track performance using the IBM Tivoli Monitor for Transaction Performance® (ITMTP). Understanding how the ARM instrumentation interacts with the ITMTP and how to implement the proper calls to the ARM libraries is the first step in being able to monitor your applications. This article shows you how to make the calls to the ARM libraries and where to place these calls within your modules to make your application visible to ITMTP.

Date:  07 Oct 2005
Level:  Intermediate

Activity:  2307 views
Comments:  

Introduction

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.

History of ARM

The Application Response-time Measurement standard was developed in 1996 by a consortium lead by Tivoli and Hewlett-Packard. A year later, in 1997, ARM 2.0 was released by the CMP (Computer Measurement Group) which was made up from the partners who contributed to the original release. A major improvement in ARM 2.0 was the introduction of correlators that could associate transactions to the desired business logic. Furthermore, correlators could pass between applications to provide high-level view of the processes being modeled. ARM 1.0 and ARM 2.0 were implemented in the C language. ARM 3.0 introduced a java implementation. The current standard is ARM 4.0 version 2 which is available for both C and Java applications.

Overview of ARM and ITMTP

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.

A Sample Module

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
Apache 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.
Apache Module Architecture

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           */
};


Getting Started

Required Software

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.

Loading the Sample Module

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.


Writing the Instrumentation

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.

Starting the Transaction

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;
}

Stopping the Transaction

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; 
}

APR Memory Management

It is not necessary to free memory allocated for use by the module. Memory allocation is done from a pool which is automatically released when the module completes its processing. See Memory Pool Functions for more information on APR memory management.

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.


Testing the Module

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.


Discovering the Transaction

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
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
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
View Discovered Transactions

If the application list is empty, click the manual data roll-up button. Rollup Button Image. 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).


Listening for Transactions

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
Create 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
Configure 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)
Configure 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
Configure Listening Policy cont

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.


Viewing the Results

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
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
Dashboard - Policy

Finally, click the topology icon Topology View 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
Topology

Conclusions

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.

What's Next?

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.



Download

DescriptionNameSizeDownload method
Complete code listings of sample moduledw_armplugins.zip11.5KBHTTP

Information about download methods


Resources

About the author

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.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

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=Tivoli
ArticleID=95211
ArticleTitle=Application Management for Web Servers: Developing an ARM-Managed Web Server Plug-in
publish-date=10072005
author1-email=mullenda@us.ibm.com
author1-email-cc=

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.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

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).

Special offers