[Libreoffice] Assertions and Logging
Norbert Thiebaud
nthiebaud at gmail.com
Mon Nov 21 21:35:15 PST 2011
On Fri, Nov 18, 2011 at 8:25 AM, Stephan Bergmann <sbergman at redhat.com> wrote:
>>
>> Second, at runtime the environment variable SAL_LOG further limits
>> which
>> macro calls actually generate log output. The environment varialbe
>> SAL_LOG
>> must either be unset or must match the regular expression
The run tine flexibility is a great feature, but the proposed
implementation is scary perf-wise
you don't want to re-parse the log-config at every log message.
You need to parse it once and for all... and not use string but enum
to identify the module/category you want to trace.
as a one-time steup cost you parse you env variable and initialize a
static array, which for each module/category contain the max
acceptable level of log
(0 = no log, 1=error, 2=warn, 3=info (4=debug?)
the test of log-ability should be a simple if( array[module] >=
level) and the macro writtin so that the no-trace path is as cheap as
possible.
To illustrate (this is for pure C where each 'module' actually have a
init_module function to dynamically register themselves to the tracing
system... that may not work nicely in c++ (ironically), but the
general gist is the same:
(excerpt)
header:
#define _msgs_out(rc) { msgs_trace_intern("%s <-- 0x%x", __func__, rc);};
#define _msgs_cond(lvl) if((lvl <= MSGS_BUILD_TRACE_LEVEL) && (lvl <=
MSGS_CONTEXT->level))
#define msgs_major _msgs_cond(LVL_MAJOR) msgs_trace_intern
#define msgs_normal _msgs_cond(LVL_NORMAL) msgs_trace_intern
#define msgs_minor _msgs_cond(LVL_MINOR) msgs_trace_intern
#define msgs_detail _msgs_cond(LVL_DETAIL) msgs_trace_intern
#define msgs_verbose _msgs_cond(LVL_VERBOSE) msgs_trace_intern
#define msgs_debug _msgs_cond(LVL_DEBUG) msgs_trace_intern
#define msgs_logorrhea _msgs_cond(LVL_LOGORRHEA) msgs_trace_intern
#define msgs_uncond msgs_trace_intern
static inline void msgs_trace_intern(const char format[], ...)
{
va_list list;
va_start(list, format);
msgs_do_trace(MSGS_CONTEXT, format, list);
va_end(list);
}
here MSGS_CONTEXT could be &g_aModules_Context[module_id] , modifying
the api above, adding a module_id parm (in my case the module_id is
implicit based on the location of the trace)
Note: the lvl <= MSGS_BUILD_TRACE_LEVEL in _msgs_cond means that the
whole things is optimized out at compile if the test is false (both
part of the test are actually build time constant. the second part f
the test means thta the test cost just a couple of integer compare to
fail.
Note that I have an intermediary static inlinee msgs_trace_intern due
to the fact that I use a static variable MSGS_CONTEXT, static to each
'module'... in you case you do not need that, if you do a full
centralized pre-registration.
Note that you can use:
log(writer,....)
and in the define of the log macro use module ## _LOG_ID to refer to
the enum value, and #module to have a pretty sting to print, so that
your log still show a human readable module name
for example, I use something like :
/* We need two macro here, to have a proper expansion of the 'module'
parameter */
#define CORE_DECLARE_MODULE(module) CORE_DECLARE_MODULE2(module)
#define CORE_DECLARE_MODULE2(module) \
static struct msgs_module_context g_context = { module ## _MODULE_ID
, -1, 0, 0, NULL, #module}
to define my module_level context
Norbert
More information about the LibreOffice
mailing list