Threads Module User's Guide : PART III Foundation Packages : Chapter 6 The Execution Tracing Package : Controlling Trace Output
Controlling Trace Output
The Execution Tracing package provides many ways to filter trace output, so it is useful to compare them all in one place.
1. Using the RW_USER_TRACE_LEVEL macro at compile time actually compiles out the code that generates trace messages less severe than the specified level.
2. Using the RW_TRACE_LEVEL environment variable at runtime prevents the trace manager from forwarding events that are less severe than the level specified.
3. Any events that pass the first two “filters” can be filtered using RWTraceLevelFilter or any filter you create.
The RW_USER_TRACE_LEVEL Macro
The first method is the RW_USER_TRACE_LEVEL macro. This macro must be defined before the rw/trace/trace.h header file is included, either in your code or on the command line for your compiler. The macro is set to a number between 0 and 8, with 0 meaning “compile out all trace macros” and levels 2 through 8 corresponding to severity levels discussed in “Trace Severity Levels”.
The RW_USER_TRACE_LEVEL macro determines which event generation macros are actually compiled into your code. The default level is 5 (INFO). If you don’t compile in a particular trace level, you can’t filter it using either of the two methods that follow. For this reason, you may want to define this macro to 8 to compile in all macros and then use one of the methods that follow to control the filtering at runtime. The runtime filtering methods are computationally more expensive than filtering at compile time, because trace events are still generated at runtime and just filtered out, whereas with compile-time filtering, they are never even generated.
The RW_TRACE_LEVEL Environment Variable
The second method is the RW_TRACE_LEVEL environment variable, which the trace manager uses to “pre-filter” trace events. The environment variable can be set to FATAL, ERROR, WARNING, INFO, TEST, DEBUG, ENTRY, or NONE to filter out all trace events. This facility defaults to ENTRY if the environment variable is left unset. The default allows all trace messages through to clients, so if you choose not to use this facility, you can safely ignore it.
Using the RW_TRACE_LEVEL environment variable is less efficient than compile-time filtering with the RW_USER_TRACE_LEVEL macro, because the trace events are still generated. The environment variable is slightly more efficient than using a level filter, however. Like all environment variables used by the Execution Tracing package, RW_TRACE_LEVEL is checked only once, when the program starts. If you need to control trace output by severity level while the program is executing, you must use a level filter.
The RWTraceLevelFilter Class
The final method of filtering is the RWTraceLevelFilter, as discussed in “Using RWTraceLevelFilter”. The level filter is the least efficient alternative, but it provides the most control, because the filtering level can be adjusted at runtime. Since it is a true filter, you can combine it with other filters and clients in many different ways to get exactly the tracing output you require.
Combining All Filtering Methods
The Execution Tracing package provides three ways of filtering by severity level to allow you the greatest flexibility in designing the tracing architecture for your applications. They were meant to be used together, and with the filtering of events by package, class and function using environment variables. The following sections detail some tracing scenarios that combine all the filtering mechanisms. You can use these as a basis for your systems.
Setup #1:
Set the RW_USER_TRACE_LEVEL macro to 8 to compile in all macros and use the RW_TRACE_LEVEL environment variable to control trace output. Don’t use a level filter. This setup provides enough control for most systems, and it doesn’t require the added complexity of inserting a level filter into your application.
Setup #2:
Set the RW_USER_TRACE_LEVEL macro to 3 (ERROR), don’t set the RW_TRACE_LEVEL environment variable, and use an RWTraceOstreamClient to log all events to a file. This setup could be used for the release version of a product. FATAL and ERROR messages are logged to a file, which can be emailed to your support staff to aid in fixing bugs in your product. You could even create a client that opens a socket and automatically emails any FATAL and ERROR messages to your support email address over the Internet.
Setup #3:
Set the RW_USER_TRACE_LEVEL macro to 0. This compiles out all trace macros. Use this setup for fully-debugged release versions of software, where execution speed is paramount.