Troubleshooting programmed extensions

Chances are, you're going to encounter a few bumps when developing an IBM Director extension. This topic provides several tools and tips to aid in debugging extensions, including how to manipulate server registry entries which control debug output and how to use the IBM Director logging facility.

Subtopics

Changing IBM Director Server registry entry settings

Two registry entries are located on and associated with the IBM Director Server machine. You might need to modify them when debugging an extension. The registry entries are located under the HKEY_LOCAL_MACHINE\SOFTWARE\Tivoli\Director\CurrentVersion key.

LogOutput
This key determines if output directed toward STDOUT (for example, System.out.println), or STDERR (for example, System.err.println), is written to a log file. By default, IBM Director does not redirect standard output to a log file. To turn logging on, change the LogOutput value from 0 to 1.

When logging is turned on, a log file is created for each Java virtual machine (JVM) launched, including the server and each extension configured to run in a separate JVM, as defined by the server task property sameJVM:false. The log file is written into the log subdirectory of the directory where the IBM Director Server is installed. The log is assigned the name of the class name of the server class defined in your extension's properties file. For example, in the BobCoFileExplorer sample, the server property specified in the task's properties file is com.BobCo.FileExplorer.BobCoFileExplorerServer. The output file for this extension is com.BobCo.FileExplorer.BobCoFileExplorerServer.stdout. Statements that write to STDOUT or STDERR, such as exceptions, are written to this file.

Controlling IBM Director logging

Instead of writing STDOUT and STDERR calls to a file, you can use another option that might be more helpful. Director provides a logging facility called reliability, availability, and serviceability (RAS). The RAS package is com.tivoli.twg.log. The RAS package consists of several classes, but you need only to use the com.tivoli.twg.log.TWGRas class to take advantage of the RAS facility. The TWGRas class provides simplified methods for logging trace information. Some of these methods are described in the remainder of this section; however, all methods are described in the TWGRas class.

Note:  All functions in the TWGRas class are static, consequently you never need to create an instance of this class.

The RAS logging facility allows you to trace selectively one or more IBM Director extensions. The logging facility knows which trace methods are associated with each extension by a unique identifier that is passed in as the first parameter on the logging methods. You might have noticed several integer constants that are defined in TWGRas, such as ENGINE or MONITORS. These constants are already used by IBM Director extensions to differentiate trace messages from the extensions included with IBM Director. The TWGRas class also declares several other unused constants (EX0 through EX7) that you can use to control logging in your extension.

If you are running outside of the IBM Director's server or console JVM, your server must call TWGRas.initialize() to initialize the RAS logging facility for your JVM. There are several methods within the TWGRas class that can be used to initialize the RAS facility. The simplest method takes no parameters. This method defaults the RAS log file to a file named TWGRas.log. You can initialize RAS so that your RAS statements are written to a different log file; simply use the initialize function which accepts a string indicating the log file name to write to.

Specifying methods to influence logging output

Depending on the method used to log information, the RAS facility formats the message text differently to help you trace the flow of your program. For example, when a message is written using the method TWGRas.entry(), the text output is formatted as:

sec.min.hour.day -> method_entered

where the period-delimited integers sec.min.hour.day indicate the time the message is written, -> indicates that a method entry follows, and method_entered indicates the type of logging method that was used to write the message. An actual entry would format as:

09.57.23.319 -> TWGRas.entry()

The following table shows the different methods used to log RAS messages.

Symbol Method Name Purpose
-> TWGRas.entry() Method entry
<> TWGRas.entryExit() Method entry and exit
-- TWGRas.debug() Debug data
!! TWGRas.error() Error data
## TWGRas.dump() Dump binary data
<- TWGRas.exit() Method exit

The dump() method allows you to log a large amount of data to a log file. The output of this function would look like:

09.57.23.319 ## a big dump
 00000000: 0001020304050607 08090A0B0C0D0E0F *................*
 00000010: 1011121314151617 18191A1B1C1D1E1F *................*
 00000020: 2021222324252627 28292A2B2C2D2E2F * !"#$%&'()*+,-./*
 00000030: 3031323334353637 38393A3B3C3D3E3F *0123456789:;<=>?*
 00000040: 4041424344454647 48494A4B4C4D4E4F *@ABCDEFGHIJKLMNO*
 00000050: 5051525354555657 58595A5B5C5D5E5F *PQRSTUVWXYZ[\]^_*
 00000060: 6061626364656667 68696A6B6C6D6E6F *`abcdefghijklmno*
 00000070: 7071727374757677 78797A7B7C7D7E7F *pqrstuvwxyz{|}~.*
 00000080: 8081828384858687 88898A8B8C8D8E8F *...â.......ï.ìÄ.*
 00000090: 9091929394959697 98999A9B9C9D9E9F *...........¢...f*
 000000A0: A0A1A2A3A4A5A6A7 A8A9AAABACADAEAF *...ú.Ѫº¿.¬.....*
 000000B0: B0B1B2B3B4B5B6B7 B8B9BABBBCBDBEBF *...¦....+..+.++.*
 000000C0: C0C1C2C3C4C5C6C7 C8C9CACBCCCDCECF *+--........-¦-.-*
 000000D0: D0D1D2D3D4D5D6D7 D8D9DADBDCDDDEDF *-..++++++++¦_¦¦¯*
 000000E0: E0E1E2E3E4E5E6E7 E8E9EAEBECEDEEEF *aß.pSsµtFTOd8fe.*
 000000F0: F0F1F2F3F4F5F6F7 F8F9FAFBFCFDFEFF *.....).".·.vn²¦.*
 

Some versions of the error() and debug() methods take as their third parameter an object of type Throwable. These functions print the stack trace of an exception that you might want to handle. This is very useful when you want to log a nonfatal exception. For example, assume you want to open a file if it exists and you want to catch the exception if it does not exist. It might still be useful to log this information. You can code these conditions as follows:

try
{
FileInputStream in = new FileInputStream("myfile.txt");
// Read the file
}
catch (IOException e)
{
if (TWGRas.isDebugEnabled())
TWGRas.error(TWGRas.EX0, "IO Exception attempting to openfile.", e);
}

After examining the TWGRas class, you might have noticed methods with similar names with an "H" appended to the name, for example, TWGRas.entry() and TWGRas.entryH(). The methods that end with an H are high logging methods. When you use a high logging method to log a message, the message is not logged unless you have enabled high logging using the RasWatch program. Also, note that messages logged using one of the error methods are logged regardless of the components you have selected to trace.

Improving performance when logging Is enabled

Using RAS creates more processing overhead, consequently performance is affected. Most of the support for message logging is provided through the Java native interface (JNI) to a Win32 dynamic link library called TWGLogJNI.dll. Even if logging is turned off, the decision to log a message is made in the native code. To avoid the overhead of making this function call each time you want to log a message, TWGRas provides the isDebugEnabled() method. isDebugEnabled() enables you to check quickly whether the RAS facility is disabled for your component, to avoid the overhead of the logging method call and message string construction.

Note:  A check for this condition should be wrapped around each log method, so that you enable and disable RAS dynamically during the execution of your extension. You should not check if debug is enabled only once during the lifetime of your extension because this will prevent you from dynamically activating and deactivating RAS output with RasWatch.

Using RASWatch and RASDump to view log output

When you have coded RAS calls in your extension, you can view the log messages using the RasWatch.exe utility, located in the bin directory on the IBM Director Server. RasWatch enables you to view the log messages in a command window as the messages are being logged by your extension and captured in a log file. Issue RasWatch -? to view a full description of the command parameters. The parameter descriptions indicate how to invoke the logging facility to monitor one or more extensions and how to enable high message logging.

By default, RasWatch views messages that are written to the default log file, TWGRas.log. If you initialize RAS to write messages to a different log file, start RasWatch using the -log parameter and indicate the filename with which you chose to initialize RAS.

In order for RasWatch to execute, the TWGLogEngine.exe process must be running. TWGLogEngine.exe is started by the IBM Director Server, therefore you do not normally start this process. There is a small time interval between the time your server extension starts and the time the IBM Director Server starts the log engine. You might have some RAS statements you would like to write during this interval. If you notice that some of your initialization messages are not being written to the log file, start TWGLogEngine.exe manually before starting the IBM Director Server. To launch TWGLogEngine the same way the server does and ensure that the log files are written to the normal directory, issue the command TWGLogEngine. If TWGLogEngine is started before the IBM Director Server, the server does not attempt to start it.

RAS messages are stored in binary format and, by themselves, are not readable. To be able to view a log file after it is created, use the RasDump utility, also located in the bin directory. RasDump takes a binary log file and converts it to a readable format similar to the output you would view using RasWatch.

In addition to providing you with valuable information to assist in debugging your extension, RAS is an excellent tool to use when your extension is deployed to a customer. Because RasWatch and RasDump are available to IBM Director customers, you can effectively gather troubleshooting information from a customer by obtaining their RAS log file(s).

Stopping and starting IBM Director

Windows platforms

It mighty be necessary from time to time to start and stop or recycle IBM Director on either the server, agent, or console. To stop the IBM Director Server on Windows, issue the following command:

net stop twgipc

To start the IBM Director Server, issue the following command:

net start twgipc

Linux platforms

To stop the IBM Director Server on Linux, use the twgend script:

twgend

To start the IBM Director Server, issue the following command:

twgstart

To stop an IBM Director agent running on NetWare, issue the following command:

unload twgipc

To start an IBM Director agent on NetWare, issue the following command:

load twgipc

Stopping and starting your server extension

While developing a programmed extension, you might stop and start the IBM Director Server more frequently than either the console or the agent because recycling the server restarts your extension if it ended abnormally or hung during attempted execution.

Stopping and starting the IBM Director Server to recycle your extension can seem excessive, and in most cases it is. In your development environment, it might be useful to restart your extension manually from the command line. To start your extension manually, go to the Classes directory under the directory where you installed IBM Director Server. The Classes directory is the directory where you should have installed the Java class files that comprise your extension. Assuming your class path includes all the IBM Director jar files, you should be able to invoke the server class file of your extension. Running your extension server manually has the added benefit of calling which write to STDOUT or STDERR (from your extension server) is displayed in the command window. You might want to run your extension server in manual mode continually during code development, not just when your extension server has ended. You can accomplish this by allowing IBM Director Server to start normally and then explicitly end your extension's JVM.

Note:  Your extension's JVM will be running only if your task is:

If you display the Windows NT task manager, you will notice several invocations of the twgsrvx executable. If your extension is defined to run outside of the IBM Director's server JVM, IBM Director uses twgsrvx to run your server extension JVM. To determine which twgsrvx executable corresponds to your extension server, issue the command:

twgsrv list

Issuing this command causes the IBM Director Server to display your extension's server class name and process identifier. Use the process ID to stop your extension server explicitly and restart it as described previously in this section.

Resetting persistent storage to include your extension

When the IBM Director Server is started, it determines if any new extensions have been added that it does not already know about. If it finds a new extension, it creates and starts a new task. From then on, IBM Director knows about the extension. Even if you have modified the files that describe your extension's properties (*.TWGExt and *.properties), this new information is not reflected the next time the IBM Director Server is stopped and restarted. To reflect changes to the files that describe your extension to IBM Director, you must delete IBM Director's persistent storage. To reset persistent storage, use TWGReset.exe, a batch file located in the bin directory of the IBM Director product.

Caution:  TWGReset deletes all persistent storage and the inventory database. The IBM Director Server is reset to almost the same state as an initial install. Any customizations that have been made are lost, such as groups, software distribution packages, scheduled jobs, monitors, etc. Do not issue this batch file while the server is running.

After you delete persistent storage, the next time you start the IBM Director Server, it no longer knows about your extension. The IBM Director Server queries the extension information again and any changes you have made to the extension property file should then be reflected by IBM Director.

Troubleshooting from the IBM Director Console

The previous sections have described how to debug code that resides on the IBM Director Server; however, you might need to debug the user interface portion of your new task. Most of the facilities you have for debugging your extension server can be used to debug your extension code on a machine that has the IBM Director Console installed.

Like the IBM Director Server, the IBM Director Console does have the facility to capture STDOUT and STDERR and pipe it to a file. This is accomplished using the same registry key LogOutput. If this registry entry's value is 1, then output directed toward STDOUT, or STDERR will be written to a file named com.tivoli.console.ConsoleLauncher.stdout located in the Log directory. Similar to debugging the server, you might want to change the NoJIT registry key value from 0 to 1 to capture line numbers in the event of the console throwing an uncaught exception.

You can use the RAS facility on the IBM Director Console as well. You must copy several files from your IBM Director Server installation to your IBM Director console installation and modify a server registry entry. First, copy the following files from the bin directory under the directory where IBM Director Server is installed to the bin directory under which IBM Director console is installed:

Now, using regedit.exe, modify the following server registry entry:

HKEY_LOCAL_MACHINE\SOFTWARE\Tivoli\Director\User\[computer]\[userid]\MainGUIConsole.ConsolePrefs

[computer] is the computer or domain name entered before the slash and the user ID on the IBM Director Console when logging onto the IBM Director Server.
[userid] is the user ID entered after the slash on the IBM Director Console when logging onto the IBM Director Server. The second byte of this binary data controls the IBM Director Console's use of native RAS support. The following values are used:

00
The IBM Director Console does not support RAS.
01
The IBM Director Console supports RAS using TWGRas.log as the log file.
02
The IBM Director Console supports RAS using TWGConRas.log as the log file.

Changing the value from 00 to 01 allows you to use RasWatch without having to specify a different log file in your console code. When the files are copied and the registry entry has been changed, you need to start the log engine, TWGLogEngine.exe, before starting RasWatch. Typically, you start the log engine in one command prompt by issuing TWGLogEngine.exe, and start RasWatch in another command prompt by issuing RasWatch.exe. You then start the console as you normally would from the program menu. You should now be able to view RAS messages you have logged from your extension's console code.