OVATION Collection User's Manual


  1. Overview

  2. OVATION Probes

  3. Loading the Probe Framework and Probes

  4. Using OVATION with Applications


Overview

OVATION is made of two high level logical entities. The first logical entity is one or more of the Probes that collect application related information. The other part is the Collector & Visualizer which receives the collected data and provides a textual and graphical view of the debugged process. The Probe Framework acts as a mediator between these two logical entities.

The following figure depicts how these entities and the application instrumented to use OVATION are interrelated.




We will discuss the functionality of the Collector and the Visualizer in depth in Visualization User's Manual. For now, the Collector is a process which receives data from the distributed processes instrumented using OVATION. The Visualizer provides a graphical view for collected data. In the following section we describe the functionality of the Probe Framework, and the Probes.

Probe Framework

The Probe Framework forms the core of the data collection process. It acts as a mediator between the probes and the collector process. OVATION is designed to require the minimum possible modifications to the existing applications. In order to serve that purpose, the Probe Framework relies on the ACE service configurator (refer to Chapter 18 of the TAO 1.2a Developer's Guide ), which supports the loading (initialization) of applications in a dynamically configurable manner.

Probes

The Probes are the entities which perform the collection of required data. A typical probe is intended to gather a specific type of data or is to be used in a specific scenario. For example, an RTEC Probe is intended to be used with distributed applications that use the Real Time Event Channel. On the other hand, a Milestone Probe, as the name indicates, gathers data describing a particular milestone that has been reached. It can be used with any kind of application.

For an application to use the functionality of a probe, it has to load and thus initialize the Probe. As with the Probe Framework, OVATION relies on the ACE Service Configurator to enable minimum disruption to the existing applications. All the Probes have to first register themselves with the Probe Framework. In return the Probe Framework provides them with a container pointer in which they place the collected data. The Probe framework independently accesses the collected data.

OVATION supplies a set of probes such as Snooper, Milestone, RTEC and Trace Probe that are described in the following sections. An OVATION user may load as many or as little number of probes as deemed necessary for the custom application. In addition to this, an user can write his/her own probe very easily and plug it in to the application. This feature of OVATION helps the users to have a customizable, distributed analyzer. We will describe how to develop a custom probe here.

OVATION Service Object

The application that is being instrumented to use OVATION has to load in the OVATION Service Object (Probe Framework) and the necessary probes via the service configurator file. Loading the services through service configurator file is described in the section on how to load OVATION service. The application triggers the Probe Framework with contextual information through an external triggering interface. For example, for the Snooper Probe, which gathers information about client and server requests and replies, the external interface is through the Portable Interceptors (refer to Chapter 13 of theTAO 1.2a Developer's Guide ). The contextual information includes a trigger_id which uniquely identifies the context in which the trigger is invoked.

As the next step, the probe framework triggers the probes registered with it and forwards them the same contextual information. Based on the trigger_id, the probes decide if they are the intended recipients of the trigger. And, if they are, they will collect the pre-defined relevant data and place it in the container provided by the probe framework during the registration process. The container provided by the Probe Framework is a pointer to its underlying data store. Before actually placing the data in the container, the probes form an XML data point from the collected data. The format of the XML data point must be consistent with what the collector expects.

The Probe Framework waits for any data to be placed in the container. The Probe Framework has an internal mediator which communicates with the collector process. When the data is available to the Probe Framework, it hands over the data to the mediator. The mediator sends the data to the collector either immediately or after a predefined condition is met dependent on the settings used to initialize OVATION.

The following figure provides a graphical representation of how it all works:
OVATION Probe Framework

OOVATION Probes

OVATION currently provides five probes. This section describes each probe. A description of how to write a custom probe is provided in a later section.

Snooper Probe

The Snooper Probe, also called the CORBA Invocation Probe, instruments the client and server requests and responses. The external triggering interface for this probe is through client and server request Portable Interceptors. In order to use the functionality provided by this probe, the application has to load the interceptors and the actual probe as well.

The probe gathers information such as the name of the request, arguments to the request, time when the request started and the time when the response is received, along with the process or task to which the request or response belongs. An example XML formatted output for the client request from the MessengerExample is shown below:


    <probeRecord>
        <sourceObject>IDL:Messenger:1.0</sourceObject>
        <component>Not in a Component</component>
        <source>
            <address host="DRURYLAP" taskOrProcess="MessengerTestClient(1572)" thread="400"/>
        </source>
        <startTime bits="914101983" format="3"/>
        <endTime bits="966631938" format="3"/>
        <group>
            <address host="DRURYLAP" taskOrProcess="MessengerTestClient(1572)" thread="400"/>
            <idWithinThread>1</idWithinThread>
        </group>
        <probeOutput>
            <clientRequestProbeOutput>
                <operation>send_message</operation>
                <isOneway>0</isOneway>
                <isCollocated>0</isCollocated>
                <exceptionRaised/>
                <argumentsList>
                    <parameter>
                        <argument>string</argument>
                        <mode>0</mode>
                    </parameter>
                    <parameter>
                        <argument>string</argument>
                        <mode>0</mode>
                    </parameter>
                    <parameter>
                        <argument>string</argument>
                        <mode>2</mode>
                    </parameter>
                </argumentsList>
                <sendBufferSize>0</sendBufferSize>
            </clientRequestProbeOutput>
        </probeOutput>
    </probeRecord>

As the sample client request probe output shows, additional information about the process is collected. This information includes: whether the call is collocated or not, if it is one way operation or a two way operation, and the id of the thread involved.

The Server Request Probe gathers the relevant server data at the point where the server receives the request and sends a response back to the client. The output for the server request in the Messenger example is:

<probeRecord>

        <sourceObject>-</sourceObject>

        <component>Not in a Component</component>

        <source>

            <address host="DRURYLAP" taskOrProcess="MessengerTestServer(3236)" thread="3808"/>

        </source>

        <startTime bits="925377741" format="3"/>

        <endTime bits="962569637" format="3"/>

        <group>

            <address host="DRURYLAP" taskOrProcess="MessengerTestClient(1572)" thread="400"/>

            <idWithinThread>1</idWithinThread>

        </group>

        <probeOutput>

            <serverRequestProbeOutput>

                <operation>IDL:Messenger:1.0::send_message</operation>

                <exceptionRaised/>

                <argumentsList>

                    <parameter>

                        <argument>string</argument>

                        <mode>0</mode>

                    </parameter>

                    <parameter>

                        <argument>string</argument>

                        <mode>0</mode>

                    </parameter>

                    <parameter>

                        <argument>string</argument>

                        <mode>2</mode>

                    </parameter>

                </argumentsList>

                <recvBufferSize>0</recvBufferSize>

            </serverRequestProbeOutput>

        </probeOutput>

    </probeRecord>

Any exceptions that are raised during the sequence of steps between the time when the server received the request, and before the reply is sent back, would be shown in the exceptionRaised tag. The value of the taskOrProcess in the <group> tag represents the originator of the request. And the taskOrProcess in the <source> tag represents the source of the probe output which is the recipient of the request.

When the collected data points are sent to the visualizer, they are analyzed based on the above mentioned rules. The Collector then determines the source and recipient of a call so that this information can be displayed graphically using the Visualizer.

Milestone Probe

The OVATION Milestone probe permits the manual demarcation of specific events in the application code. For example, the user may wish to know the temporal relationship of events in relation to when a specific request is received. It supports two kinds of milestones. One is an unconditional milestone and the other one is a milestone which is achieved upon reaching a condition. For example, if the server has successfully responded to 3000 requests in a day.

The external triggering interface to the above mentioned milestone functionality is supported through macros, OVATION_MILESTONE_IS_REACHED and OVATION_CONDITIONAL_MILESTONE_IS_REACHED . All the macros are described in the OVATION Macros section.

In addition to providing support to gather milestone related information, this probe also helps in the cases when the user wants to provide some additional data which does not come under a specific predefined category. This functionality is provided through the OVATION_COLLECT_USER_DATA and OVATION_CONDITIONAL_COLLECT_USER_DATA macros.

A milestone probe output from the MessengerExample would look like
    <probeRecord>
        <sourceObject>-</sourceObject>

        <component>Not in a Component</component>

        <source>

            <address host="DRURYLAP" taskOrProcess="MessengerTestServer(3236)" thread="3808"/>

        </source>

        <startTime bits="942885677" format="3"/>

        <endTime bits="942885677" format="3"/>

        <group>

            <address host="DRURYLAP" taskOrProcess="MessengerTestServer(3236)" thread="3808"/>

            <idWithinThread>1</idWithinThread>

        </group>

        <probeOutput>

            <milestoneProbeOutput>

                <description>Message is being sent</description>

            </milestoneProbeOutput>

        </probeOutput>

    </probeRecord>

Trace Probe

The Snooper Probe works only in the case of CORBA calls. To be able to instrument non CORBA calls as well, OVATION provides the Trace Probe. The Trace Probe helps gather the operation name, component to which the operation belongs to, arguments of the operation and any other data that the user wants to be tracked. The user has to invoke the OVATION_TRACE_CALL macro for this as described in the OVATION Macros section.

    <probeRecord>

        <sourceObject>PingTest Client main</sourceObject>

        <component>Not in a Component</component>

        <source>

             <address host="DRURYLAP" taskOrProcess="MessengerTestServer(3236)" thread="3808"/>

        </source>

        <startTime bits="6472627616038721" format="3"/>

        <endTime bits="6472627616038721" format="3"/>

        <group>

        <address host="DRURYLAP" taskOrProcess="MessengerTestServer(3236)" thread="3808"/>

        <idWithinThread>2</idWithinThread>

        </group>

        <probeOutput>

            <traceProbeOutput>

                <operation>test_operation</operation>

                <argumentsList>

                    <argument>test_para1</argument>

                    <argument>test_para2</argument>

                </argumentsList>

            </traceProbeOutput>

        </probeOutput>

    </probeRecord>



The Component Name, if passed in, would get reflected in the <component> tag. Anything else that is passed in will get reflected in the <argumentsList> tag.

RTEC Probe

The RTEC Probe is used for applications that use the Real Time Event Channel. The RTEC Probe helps gather information regarding suppliers, consumers and the events sent between them. The RTEC Probe, like the Snooper Probe, also relies on Portable Interceptors for gathering the information. The following is a sample output from the RTEC probe.

   <probeRecord>

        <sourceObject>-</sourceObject>

        <component>Not in a Component</component>

        <source>

            <address host="priyanka.ociweb.com" taskOrProcess="Event_Service(1551)" thread="1024"/>

        </source>

        <startTime bits="7571990242615920" format="3"/>

        <endTime bits="7571990242615920" format="3"/>

        <group>

            <address host="priyanka.ociweb.com" taskOrProcess="Event_Service(1551)" thread="1024"/>

            <idWithinThread>5</idWithinThread>

        </group>

        <probeOutput>

            <eventChannelProbeOutput>

                <isRtecEventChannel>1</isRtecEventChannel>

                <isCollocatedWithChannel>0</isCollocatedWithChannel>

                <eventType>17</eventType>

                <eventSource>1</eventSource>

                <eventSupplier eventCreationTime="7307761101796540416" eventSize="72" isDeadlineTimeout="0" isTimeoutEvent="0"/>

            </eventChannelProbeOutput>

        </probeOutput>

   </probeRecord>

The <isRtecEventChannel> entry informs if the underlying event channel is Real Time indeed. <eventType> as the name suggests, specifies the type of the event as set by the supplier. <eventSource> indicates the source of the event, the unique identifier, by which the supplier chose to identify itself.

As with the other probes, the data points sent to the collector are analyzed and shown graphically. In addition to showing the interactions between the consumer, supplier and the event service, the visualizer also provides support to view the eventSet dependencies. More about this will be described in the visualizer section.

LogWriter Probe

When an application is instrumented with OVATION, the process is analyzed and the result is flushed to the collector. To view this data with the visualizer provided by OVATION, the data needs to be written to a file. The LogWriter Probe provides a way to do it without having to modify existing code.

If the LogWriter Probe is loaded into the application, the default is to request the collector to write the data to a log file once for every 1 trigger requests sent to the Probe Framework. The default log file name to which the data is written is ovation_app.log. This behaviour can be changed using the service object directive's arguments. The Probe supports two arguments.

-OVATIONLogFileName file_name is to be used to change the default name of the file to which the data is written.
-OVATIONLogWriteCounter number is to be used to change the default count of the triggers after which the data is to be written to the log.

This entry should be the last of the probes that are loaded in to the application to be able to send as many data points as possible. The catch to this way of writing the analyzed data to a log file is that there is a chance that some of the data points are not written to the log if the value of the counter is not one (1). This option works great with standalone applications which cannot be shutdown gracefully except through a signal or for applications that are running continuously.

Developing Custom OVATION Probes

OVATION provides the support for the users to add custom probes to gather any custom information that the OVATION probes do not analyze. This section describes how to write a new probe and what to modify by trying to write a custom probe. The Custom_Probe that is being implemented here will get the current working directory and send it to the collector. For simplicity, the LINUX system call ::getcwd is used for retrieving the current working directory and the fact that the format is not the same on all operating systems is not taken into consideration. The first step is to create a Probe class.

The OVATION library provides a base class called Probe_i. All probes must be derived from this base class and implement each of the virtual functions. First we will start with the interface, Custom_Probe.h

#include <probefwk/Probe_i.h>

class Custom_Probe : public virtual  Probe_i
{
  public:

   Custom_Probe ();

   /// Destructor
   virtual ~Custom_Probe (void);

   /** 
    * init method that will be invoked by the service configurator 
    * framework when the Custom_Probe service object is loaded.
    */ 
   virtual int init (int argc, char *argv[]);

   /**
    * Get the information that the probe has to provide
    * asking it to place the content in 'container_ptr'
    * The 'input_data' has incoming data that will be
    * useful.@see Probe_i::collect
    */
   virtual int collect (TriggerID trigger_id, void *input_data);  

   /**
    * The accessor through which the probe framework will set the 
    * data store where the probe has to place the data points to be 
    * eventually sent to the collector.
    */
   virtual void set_container (PROBE_DATA_STORE *container);

private:

  /// Pointer to the container where the datapoints are to be placed.
  PROBE_DATA_STORE *container_;
};

The init method is used to register the Probe with the Probe Framework. The Framework, in turn, invokes the set_container method of the probe to give a pointer to the container. The Probe Framework will invoke the collect methods of each probe registered with it when a trigger is invoked from the application.

Now, let us implement the Custom Probe.

#include "Custom_Probe.h"
#include <probefwk/Probe_Framwork_i.h>
Custom_Probe::Custom_Probe ()
    : container_ (0)
 {
     // Constructor
 }

Custom_Probe::~Custom_Probe ()
{
}
int
Custom_Probe::init (int /* argc */, char * /* argv */ []) 
{
   // Register this Probe
   Probe_Framework_i::instance ()->register_probe (this); 
   return 0;
}
int
Custome_Probe::collect  (TriggerID trigger_id,
                                           void *input_data)
{
  int result = 0;
  switch (trigger_id)
    {
     case CUSTOM_PROBE_CWD:
         // Invoke the private helper to get the current wd
          result = this->get_current_wd (input_data);      
        break;
    case default:
        break;
    }
  return result;
}

void
Custom_Probe::set_container (PROBE_DATA_STORE *container)
{
   this->container_ = container;
}

int
Custom_Probe::get_current_wd (void *input_data)
{ 
   // Initialize a buffer of sample size 1024
   char buf[1024];
   // Invoke the OS call to get the current working directory.
   // For simplicity of code, the error checks are not done here.
   ::getcwd (buf, 1024);
   // Make a collectable datapoint from the arguments 
   ACE_CString probe_output = "<probeOutput>";
   probe_output += "<customProbeOutput>";
   probe_output += "<working_dir>";
   probe_output += CORBA::string_dup (buf);
   probe_output += "</working_dir>";
   probe_output += "</customeProbeOutput>";
   probe_output += "</probeOutput>"; 
  
   // Please refer to the Instrumentation.idl for the structure of a Datapoint.
   OVATION_Instrumentation::Datapoint datapoint;
   datapoint.probeOutput    = CORBA::string_dup (probe_output.c_str ());
   CORBA::String_var sourceObject =  OVATION_GET_CURRENT_CALLER_DESCRIPTION ();
   datapoint.sourceObject   = CORBA::string_dup (sourceObject.in ());

   CORBA::String_var component = OVATION_GET_COMPONENT_DESCRIPTION (OVATION_GET_CURRENT_CALLER_DESCRIPTION());
   datapoint.component      = CORBA::string_dup (component.in ());
   OVATION_Globals::Address source = OVATION_Local::getMyAddress ();
   datapoint.source_host    = source.host; 
   datapoint.source_taskOrProcess = source.taskOrProcess;
   datapoint.source_thread  = source.thread; 
   datapoint.format         =   OVATION_TimeService::NANOS_SINCE_SYSTEM_BOOTED;

   OVATION_TimeService::Timestamp time = OVATION_Local::getCurrentTime ();
   datapoint.startTime      = time.timeBits;   datapoint.endTime        = time.timeBits;
   OVATION_Globals::DatapointGroupId group = OVATION_Local::getNewDatapointGroupId();
   datapoint.group_host            = group.originator.host;  
   datapoint.group_taskOrProcess   = group.originator.taskOrProcess; 
   datapoint.group_thread          = group.originator.thread;  
   datapoint.group_idWithinThread  = group.idWithinThread;

   // Invoke the helper to convert the collectabledatapoint to XML format
   OVATION_Instrumentation::XML_Datapoint xml_datapoint;
   xml_datapoint = this->convert_to_xml (datapoint);

   //  Instantiate a ACE_Data_Block
   ACE_Data_Block *db;
   ACE_NEW_RETURN (db,  ACE_Data_Block, -1);
   db->base (ACE_const_cast (char *, CORBA::string_dup (xml_datapoint.in ())),    
             ACE_OS::strlen (xml_dp.in ()) + 10);

   // Create a message block
   ACE_Message_Block mb (db->duplicate ());
   // Bind the data point to the container that is set by the probe framework.
   int result =    
       this->container_->bind (CORBA::string_dup (this->my_id_), 
                               ACE_Message_Block::duplicate (&amp;mb));
   // error checks
   return 0;
}

The code for the helper method convert_to_xml() is not shown here as it is a simple string concatenation to put the collected data into an XML formatted string.

Last but not the least, use the service configurator macros to make the Probe dynamically loadable. The macros used are described below. Please refer to the ACE Service Configurator as described in Chapter 18 of the TAO 1.2a Developer's Guide for more information about the macros.

The Service Object is declared in the header file as:

ACE_STATIC_SVC_DECLARE_EXPORT (Custom, Custom_Probe)

ACE_FACTORY_DECLARE (Custom, Custom_Probe)

and is to be defined in the implementation file as

ACE_STATIC_SVC_DEFINE (Custom_Probe,
                       ACE_TEXT ("Custom_Probe"),
                       ACE_SVC_OBJ_T,
                       &ACE_SVC_NAME (Custom_Probe),
                       ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ,
                       0)
ACE_FACTORY_DEFINE (Custom, Custom_Probe)

Loading the Probe Framework and Probes

The directives to load OVATION and its associated OVATION probes are read from the service configurator file ( svc.conf by default or the file indicated by the -ORBSvcConf flag). A sample service configurator file is show below (see $OVATION_ROOT/examples/bin ):

dynamic Snooper Service_Object *Snooper_Probe:_make_Snooper_Plugin () "dummy"
dynamic Rtec_Probe_Plugin Service_Object *Rtec_Probe:_make_Rtec_Probe_Plugin () ""
dynamic Ovation Service_Object *OVATION:_make_Ovation () "TraceTest"
dynamic Snooper_Probe Service_Object *Snooper_Probe:_make_Snooper_Probe () ""
dynamic Milestone_Probe Service_Object *Milestone_Probe:_make_Milestone_Probe () ""
dynamic Trace_Probe Service_Object *Trace_Probe:_make_Trace_Probe () ""
dynamic Rtec_Probe Service_Object *Rtec_Probe:_make_Rtec_Probe () ""

dynamic LogWriter_Probe Service_Object *LogWriter_Probe:_make_LogWriter_Probe () ""

Loading the OVATION Service Object

The directive shown below causes the ACE Service Configurator to load in the OVATION service object which is essentially the Probe Framework. The first argument (in this case, the only argument, TraceTest) gives the name of the process that will be displayed in the OVATION visualizer. Other arguments can be passed to the service object which include specifying the collector IOR, the endpoint where the collector is running, specifying a predefined number for the datapoints after which they have to be flushed to the collector.

dynamic Ovation Service_Object *OVATION:_make_Ovation () "MessengerTestServer"

Loading the Snooper Probe

The OVATION Snooper probe is based on Portable Interceptors. The directive entry shown below loads in the client and server interceptors, which are the external triggering interfaces used for the Snooper Probe.

dynamic Snooper Service_Object *Snooper_Probe:_make_Snooper_Plugin () ""

We load the interceptors and the probe that does the actual work in two directives so as to distinguish the functionality. The Snooper_Plugin is the trigger which informs OVATION to start collecting CORBA invocation related data.

The following directive loads the Snooper probe.

dynamic Snooper_Probe Service_Object *Snooper_Probe:_make_Snooper_Probe () ""

Loading the Milestone Probe

The Milestone probe can be dynamically loaded using the following directive:

dynamic Milestone_Probe Service_Object *Milestone_Probe:_make_Milestone_Probe () ""

Loading the RTEC Probe

Similar to the Snooper Probe, the first directive causes the interceptors to be "plugged in" while the second directive below loads the specific RTEC probe.

dynamic Rtec_Probe_Plugin Service_Object *Rtec_Probe:_make_Rtec_Probe_Plugin () ""
dynamic Rtec_Probe Service_Object *Rtec_Probe:_make_Rtec_Probe () ""

Loading the Trace Probe

The OVATION Trace probe is useful for tracing non-CORBA invocations. This probe can be loaded with the following directive:

dynamic Trace_Probe Service_Object *Trace_Probe:_make_Trace_Probe () ""

Loading the LogWriter Probe

The OVATION LogWriter probe is useful for writing the gathered data to a log. This probe can be loaded with the following directive:

dynamic LogWriter_Probe Service_Object *LogWriter_Probe:_make_LogWriter_Probe () "dummy -OVATIONLogFileName TraceTest.log -OVATIONLogWriteCounter 20"

or without no arguments as

dynamic LogWriter_Probe Service_Object *LogWriter_Probe:_make_LogWriter_Probe () ""

Using OVATION With Applications

The instructions below detail the changes required to instrument your application with OVATION. The assumptions are that you have:

  1. OVATION installed correctly
  2. The OVATION_ROOT environment variable correctly specified
  3. OVATION is compiled as mentioned in the installation instructions.

Portable Server Library

Since the Snooper Probe and the Rtec Probe depend on Portable Interceptor support, the application has to be linked against the TAO_PortableServer library to use either of the probe's functionality. Unless the application is a pure client, this library is most likely already being linked. If not, here are the instructions for Windows and UNIX builds.

In UNIX Makefiles, LDLIBS is the usual target that contains a list of external libraries to link with. If the application uses the LDLIBS for linking in libraries, add the following entry as is:

LDLIBS += -lPortableServer

If LDLIBS is not being used, add PortableServer library to the similar target. For example, in the Messenger example that is used in this documentation, TAO_CLNT_LIBS is used to hold the list of libraries for the MessengerClient. In this case, the entry that should be added to the Makefile is:

TAO_CLNT_LIBS += -lTAO_PortableServer

In this case, the entry should be added after the include files in the existing makefile.

On Windows, the project settings should be updated as:

  1. In the Project Settings, click on the "Link" tab.
  2. Under the General category, in Object/library modules, add "TAO_PortableServerd.lib".

Write Process Data to Log File

When an application is instrumented with OVATION, the process is being analyzed and any log data are formatted into an XML formatted strings and sent to the collector. The Collector supports writing the log data to a file to be viewed by the user either in any text editor or with the visualizer provided by OVATION. There are different ways to request the collector to write to a log file.

One way is with the help of the macros provided by OVATION. The OVATION_WRITE_COLLECTOR_LOG macro serves this purpose. In order to use this macro, the application code should include the $(OVATION_ROOT)/probefwk/Instrumentation.h  file. The typical place to invoke this macro is at the end of the client code where the control is reached before the application terminates. But, it can be invoked at any point where the gathered data points are to be written to a log file. After adding this macro to the code, the application has to be recompiled.

The following changes should be made for the UNIX Makefile:

CPPFLAGS += -I$(OVATION_ROOT)/src/cplusplus
LDFLAGS += -L$(OVATION_ROOT)/lib

And lastly, OVATION library has to be linked in addition to the existing list of linked libraries. As mentioned in the Portable Server Library section above, LDLIBS is the usual target that contains a list of external libraries to link with. If the application uses the LDLIBS for linking in libraries, add the following entry as is:

LDLIBS += -lOVATION

Otherwise add OVATION to the similar target. For example, in the Messenger example that is used in this documentation, TAO_SRVR_LIBS is used to hold the list of libraries for the MessengerServer. In this case, the entry that should be added to the Makefile is:

TAO_SRVR_LIBS += -lOVATION

Similarly, for the MessengerClient, it is TAO_CLNT_LIBS. Accordingly, an entry for that should also be added as

TAO_CLNT_LIBS += -lOVATION

Again in this case, the above two entries are to be added after the include files which instantiate the TAO_SRVR_LIBS and TAO_CLNT_LIBS targets.

For Windows builds, the project settings should be modified in the following ways:

  1. In the Project Settings, click on the "Link" tab.
  2. Under the General category, in Object/library modules, add "ovation.lib".
  3. Under the input section, for the Additional library path, add $(OVATION_ROOT)/lib
  4. Click on the C++ tab.
  5. Under the general section, in the Preprocessor definitions, add OVATION_HAS_DLL=1 if the OVATION library was built as dynamic or OVATION_HAS_DLL=0 if the library was built as a static.
  6. In the Preprocessor section, for additional include directories, add $(OVATION_ROOT)/src/cpluscplus.
  7. Save the settings and rebuild your application.

Another way which would avoid making code changes is to use the LogWriter Probe which is described in the Probes section.

With the above mentioned changes, you are ready to instrument your code with OVATION and also save the gathered information to a log file.

Copyright © 2006 Object Computing, Inc. All rights reserved. | Privacy Policy