The "basic" serviceability routines are the following:
· DCE_SVC_DEFINE_HANDLE( )
This is a macro that can be used instead of dce_svc_register( ) to register a table (it does this by means of a global
variable created at compile time). It could have been used in the hello_svc.c code as follows, with exactly the same results as from using dce_svc_register( ):
DCE_SVC_DEFINE_HANDLE(hel_svc_handle, hel_svc_table, "hel");
/* handle | | */
/* table | */
/* component name */
Note that either DCE_SVC_DEFINE_HANDLE( ) or dce_svc_register( ) must be called before the interface can be used.
· dce_svc_register( )
This is the function call for registering a serviceability message table. Either it or DCE_SVC_DEFINE_HANDLE( ) must be called before any routines can be called to display or log messages. An example of its use can be seen in the illustrated hello_svc.c code.
· dce_svc_unregister( )
This is the function call for destroying a serviceability handle. Calling it closes any open message routes and frees all allocated resources associated with the handle. However, it is not usually necessary to call this routine since the normal process exit will perform the required cleanup.
The routine could have been called at the end of the hello_svc.c application as follows:
dce_svc_unregister(hel_svc_handle, &status);
where hel_svc_handle is the serviceability handle that was originally returned by the call to dce_svc_register( ), or filled in by the DCE_SVC_DEFINE_HANDLE( ) call.
· dce_svc_set_progname( )
This function sets the application's program name, which is included in all messages. In this way, multiple programs can write messages to the same file and the messages will remain distinguishable.
For example, this routine could have been called in the hello_svc.c code, as follows:
dce_svc_set_progname("hello_program", &status);
The message printed by the program would, as a result, have looked like the following:
1994-04-05-20:13:34.500+00:00I----- hello_program NOTICE hel main ...
Hello World
instead of looking like this:
1994-04-05-20:13:34.500+00:00I----- PID#9467 NOTICE hel main ...
Hello World
where the default process ID information has been replaced by the string hello_program in the first example. The second example shows what the message looks like if the routine is not called. The PID#nnnn value is the value returned by getpid( ).
This call is optional.
· dce_svc_printf( )
This is the normal call for writing or displaying serviceability messages. It cannot be called with a literal text argument; instead, the message text and other necessary information must be pre-specified in a file that is processed by the sams utility, which in turn outputs sets of tables from which the messages are extracted for output. The tutorial in Simple Serviceability Interface Tutorial provides a brief example of how this is done.
There are two main ways in which to call the routine. If a message has been defined in the sams file with both sub-component and attributes specified, then the sams output will include a convenience macro for the message that can be passed as the single argument to dce_svc_printf( ), for example:
dce_svc_printf(HEL_S_HELLO_MSG);
The convenience macro's name will be generated from the uppercase version of the message's code value (as specified in the sams file), with the string _MSG appended.
If a convenience macro is not generated, or if you want to override some of the message's attributes at the time of output, then you must call the routine in its long form. For the hel_s_hello message, such a form of the call might look as follows:
dce_svc_printf(DCE_SVC(hel_svc_handle, ""), hel_s_main,\
svc_c_sev_error | svc_c_route_stderr, hel_s_hello);
DCE_SVC( ) is a macro that must be passed as the first argument to dce_svc_printf( ) if a convenience macro is not being used. It takes two arguments:
- The caller's serviceability handle
- A format string for the message that is to be output
The format string is for use with messages that have been coded with argument specifiers. The hel_s_hello message had no argument specifiers, so an empty string is passed here to DCE_SVC. For an example of printing a message with arguments, see the end of this subtopic.
The remaining arguments passed to dce_svc_printf( ) are as follows:
- Subcomponent table index
This symbol was declared in the sub-component list coded in Part II of the sams file; its value is used to index into the subtable of messages in which the desired message is located.
- Message attribute(s)
This argument consists of one or more attributes to be applied to the message that is to be printed. Note that you must specify at least a severity here (for a list of message severity values, see Specifying Message Severity). Multiple attributes are ORed together, as shown in the example.
There are four categories of message attributes:
routing
The available routing attribute constants are
- svc_c_route_stderr
- svc_c_route_nolog
However, most routing is done either by passing specially formatted strings to dce_svc_routing( ) or by environment variable values. See How to Route Messages for more detailed information.
severity
The available severity attribute constants are
- svc_c_sev_fatal
- svc_c_sev_error
- svc_c_sev_warning
- svc_c_sev_notice
- svc_c_sev_notice_verbose
For more detailed information, see Specifying Message Severity.
action
The available message action attribute constants are
- svc_c_action_abort
- svc_c_action_exit_bad
- svc_c_action_exit_ok
- svc_c_action_brief
For more detailed information, see Message Action Attributes.
debug level
Nine different debug levels can be specified. For more detailed information, see Using Serviceability for Debug Messages .
- message ID
This argument consists of the message's code, as declared in the sams file.
As an example of how to use format specifiers in messages, consider the following sams file fragment, in which we define a second message for the hello_svc.c application:
start
code hel_s_testmessage
text "This message has exactly %d not %d argument(s)"
explanation "This message is to show how to pass arguments"
action "None required."
end
The message could be printed by a call like the following:
dce_svc_printf(DCE_SVC(hel_svc_handle, "%d%d"), hel_s_main,\
svc_c_sev_notice | svc_c_route_stderr,\
hel_s_testmessage, 2, 7);
Note the format specifiers passed in the format string to DCE_SVC, and the argument values passed at the end of the argument list. This call would cause the following message to be printed:
1994-04-06-20:06:33.113+00:00I----- hello NOTICE hel main hello_svc.c line_nr 0xa444e208
This message has exactly 2 not 7 argument(s)