PreviousNext

Dynamically Filtering Messages Before Output

The serviceability interface provides for a "hook" into the message-output mechanism that allows applications to decide at the time of messaging whether the given message should be output or not. The application defines its own routine to perform whatever checking is desired, and installs the routine with a call to dce_svc_define_filter( ).

In addition, an application that installs such a message-filtering routine can also define and install a routine that can be called remotely to alter the operation of the filter routine. The remote-control routine is installed by the same call to dce_svc_define_filter( ).

The two routines must have the following signatures. The yes/no routine you define and install is as follows:

boolean your_filter_routine(

dce_svc_prolog_t prolog,

va_list args)

The filter remote-control call is as follows:

void your_filter_remote_control(

idl_long_int arg_size;

idl_byte *arg;

error_status_t *status)

Once installed, the filter routine will be automatically invoked every time a serviceability routine is called to output a message. The filter receives a prolog argument that contains all the pertinent information about the message. If the filter returns TRUE, the message is output per the original serviceability call. If the filter returns FALSE, the message is not output. The information in the prolog allows such decisions to be made on the basis of severity level, subcomponent, message index, and so on. Its fields are as follows:

dce_svc_handle_t handle
Serviceability handle of the application writing the message.

int version
Version number of the interface that generated the message.

utc_t t
Pointer to an opaque binary timestamp containing the time at which the message was written. The opaque timestamp can be converted to a tm structure by calling one of the DCE DTS utc_...( ) routines.

const char *argtypes
The format-specifier string for the message.

unsigned32 table_index
The subcomponent table index (for example, hel_s_main as defined in the sams file in Defining the Message .

unsigned32 attributes
Message attributes, ORed together.

unsigned32 message_index
Index number of the message in the message table (for example, hel_s_hello in the example in Defining the Message ).

char *format
Format argument values for the message.

const char *file
Filename string identifying the file to which the message is to be output.

char progname[dce_svc_c_progname_buffsize]
Program name string, set by the application's call to dce_svc_set_progname( ).

int line
Line number in file from where the message was printed.

pthread_t thread_id
ID of the application thread that is causing the message to be output.

The filter remote control routine is part of the remote serviceability interface, which is described in detail in Using the Remote Serviceability Interface. Its operation is simple. If filter remote control is desired, the filter routine should be coded so that its operation can be switched to the various desired alternatives by the values of static variables to which it has access. These variables are also accessible to the remote control routine, and can be changed by it. The filter routine receives an argument string (which it uses to set the variables) whose contents are entirely application defined.

The following code fragments show a skeleton filter that can be added to the hello_svc.c example at the beginning of this topic (Coding the Serviceability Calls ):

#include <stdarg.h>

#include <dce/svcfilter.h>


<. . .>


/*****

* Filter routine-- once installed, this routine will be called

* automatically every time a serviceability

* routine (in our case, dce_svc_printf( )) is

* called to write a message.

*****/

boolean hel_filter(dce_svc_prolog_t prolog,

va_list args)

{


/* Code could be inserted here to test the values of static

variables that would control the operation of the filter,

and which could be altered by calling the filter control

routine below. */


printf("The progname is %s\n", prolog->progname);


if (prolog->attributes | svc_c_sev_notice)

printf("This is a Notice-type message\n");


switch (prolog->table_index)

{

case hel_s_main:

printf("Main subcomponent\n");

break;

default:

printf("Error\n");

break;

}


/* The routine returns 1, thus permitting the output

operation to go ahead; if 0 were returned here, the

operation would be suppressed ... */


return 1;


}


/*****

* Filter Control routine-- this routine is normally called

* through the remote interface.

*****/

void hel_filter_control(idl_long_int arg_size,

idl_byte *arg,

error_status_t *status)

{


/* Code would be inserted here to interpret the arg passed

and, on the basis of that, change the value(s) of one

or more static variables that control the operation of

hel_filter( ) */


}


/*****

* install_filters-- calls dce_svc_define_filter( ) to install

* the above 2 routines. Note that this must

* be done after dce_svc_register( ) is

* called, not before.

*****/

void install_filters( )

{

unsigned32 status;


dce_svc_define_filter(hel_svc_handle, hel_filter, \

hel_filter_control, &status);

}