Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


On Fri, Nov 18, 2011 at 8:25 AM, Stephan Bergmann <sbergman@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

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.