Demand Predefined Probe

From OC Systems Wiki!
Jump to: navigation, search

Demand Action: demand.ual

(Since 4.4.4a)

The predefined probe demand.ual is part of a framework for "demanding" action from another probe from the command-line at nun-time, independent of what the probed program might be doing. This is an advanced feature, but can be powerful in the right circumstances.

The demand framework is integrated into a number of predefined probes (coverage, memstat, memwatch, profile, statprof) and ready to use. The demand framework can be added to custom probes as well.

The Demand Framework

The demand framework consists of the demand.h include file, the demand.ual probe, and the apdemand command-line script.

The apdemand command is your way of requesting action.

The demand UAL needs to be included in Aprobe runs by -u demand, because it is a pre-defined UAL whose logic you can ignore.

The ap_OfferDemand() macro is invoked in the UAL APC files. You only need to look at the macro to write custom APC which offers your own actions on-demand. The macro is in $APROBE/include/demand.h, and an example of its use is at the end of $APROBE/probes/profile.apc.

Actions On-Demand From Predefined UALs

Several predefined UALs offer snapshots and other actions on user demand:

  • coverage.ual
  • memwatch.ual
  • memstat.ual
  • profile.ual
  • statprof.ual

Demand snapshots are logged like snapshots you can trigger by naming trigger functions in the config files, but demand needs no internal triggers. Instead, the trigger is a command you can enter from any shell using apdemand. This may be useful for long-running applications or applications that don't terminate and for which there is no good snapshot location or if you don't know where to place triggers.

See the documentation for those probes to see available demand actions.

Simple Probe Example

A probe can be enabled for the demand framework by including the demand.h file and then instantiating the ap_OfferDemand() macro to define actions which can be demanded from the command line. The ap_OfferDemand() macro defines the action name and a callback to perform the action.

Here is an example of that:

 #include "demand.h"

 void MyActionCallback(FILE *spool)
    // write to the demand spool file to provide status 
    fprintf(spool "starting my action...\n");

    // performs the action

    // write to the demand spool file to provide status
    fpritnf(spool, "dons my action\n");

 ap_OffserDemand(MyActionCallback, "myprobe action1");

To use the demand framework with an enabled probe you will add demand.ual to the Approve command line:

 aprobe -u my probe -u demand  MyApp.exe

To send action commands to the probe use apdemand form the command line:

 apdemand action1

Advanced Remote Control Example

Remote Control is an advanced use of demand.ual to affect a remote application while it runs, with Aprobe and UALs, of course. The demand.ual is an Aprobe predefined probe which you just include in the UAL list. To go with it, you design probes which test switches you plan to flip while the application runs. In this case, apdemand will send action demands to your probes.

In your probe APC you will define a number of boolean flags such as:

 ap_BooleanT OptionalOutputWanted = FALSE;

You also put the output code inside a conditional like:

 if (OptionalOutputWanted) { ... }

And, finally, you declare an action callback function to set the flag:

  void FlipOptionalOutput(FILE *spool) 
     OptionalOutputWanted = ! OptionalOutputWanted;
     fprintf(spool, "OptionalOutputWanted is %d\n", OptionalOutputWanted);

and register your callback function with a macro for the apdemand script:

  ap_OfferDemand(FlipOptionalOutput, "invert OptionalOutput")

then trigger callbacks while the application runs using apdemand:

 apdemand invert

From a separate, usually remote command shell, entering

 apdemand ...

dynamically updates a demand.cfg file. It is created by the ap_OfferDemand macros. It is periodically read by the demand.ual probe within the running application. When it sees an update, it triggers your callbacks. The apdemand script also manages an output "spool" file that keeps you informed about what is happening and what actions are available.

Continuing our example then, entering

 apdemand nal

triggers callbacks which contain "nal" in the registration string. You can have many switches and callback functions, each registered with a meaningful phrase in quotes. You can trigger one at a time, or several at once, by choosing a unique string fragment, or a string fragment which occurs in several registrations. Planning ahead is useful.

This model can also be used to affect application output, such as sending messages, printing, and writing to files, when the application already tests switches. Your apc coding differences are minor, using $ in your probe references to an application boolean instance.

A callback fprintf to spool is recommended. FILE *spool is passed to all callback functions. The file already has a spool header which identifies the callback by its registration string. The spool file is closed with a trailer when the callback function returns. Then apdemandsees the closing trailer and pages the spool file.

To set a number, such as a multiplier or a limit, instead of a boolean, you echo the value to a work file before triggering your callback function by apdemand. Your callback function opens the work file and reads the input with fscanf. The input value can replace or bump the controlled number. You can also read a string from a work file, being careful about the size of the area into which you put the string. A string pointer is safer to modify, with the input string copied to a malloc area. You can write scripts which echo and invoke apdemand Callbacks can also set numbers and strings in the application by echo plus demand, using $ before an application name.

In summary, remote controls are your design: boolean, numeric, and string data are your choices, you register phrases which apdemand searches for a callback function to trigger, and you write confirming feedback from your callback function. You can write spool output from callback functions which don't change anything, and thereby design remote queries of collected probe data, or application state data. Using probes in this way, you do not interface manually with the application process. Instead, your manual interface is with files in a remote working directory. Your interface to change a file can be ssh commands to the application's server, or commands in a remote window on the server, or commands in any window onto shared disk, whatever works for you.


Using demand is straightforward - just include it on the Aprobe command line using the -u option along with a demand-enabled probe:

 aprobe -u statprof -u demand myapp.exe