In general, I think that LOG_DEBUG and similar macros that evaluate code 
are unappealing because it makes it harder to understand the code, but I 
am also of the opinion that aesthetics in code are not always to be 
considered paramount.

Earlier profiling has indicated that debug logging in YXA accounts for 
about 10% of the work performed in a proxy (probably actually even more 
percents, see below). Before Erlang got SMP support, it also introduced 
a lot of unhealthy blocking (on every platform but Solaris I believe). 
I'm not sure if SMP enabled Erlang still has a big mutex around all I/O, 
so this may still be the case.

Serge Aleynikov wrote:
> I'd like to request the following logger feature.
> a. Replace the logger:log/3 call by macros:
> -define(LOG_DEBUG(A, B),  logger:log(debug, A, B)).
> -define(LOG_ERROR(A, B),  logger:log(error, A, B)).
> -define(LOG_NORMAL(A, B), logger:log(normal, A, B)).
> This way it'll be easy to exclude logging of specific types from 
> compilation when not needed.

What types of log messages actually written out to disk was made 
configurable recently, and even though probably not unmeasurable the 
performance win of using a macro like that instead of a macro that makes 
the actual log function just return immediately are probably negligible.

> 3. Replace the 3rd parameter of logger:log/3 by a macro:
> -define(LAZY(L), fun() -> L end).
> Sample call:
>    before:
>    logger:log(debug, "test ~s", [list:flatten(["one", " ", "two"])).
>    after:
>    logger:log(debug, "test ~s", ?LAZY([list:flatten(["one", "two"]))).
> Why is it needed?
> This way it'll be possible to enable/disable log level logging without 
> recompilation, and not to have performance impact because of strict 
> evaluation of parameters in the call to the logger when no logging is 
> desired.

Did you really mean "without recompilation"? If ?LAZY were defined to [] 
instead of evaluating the call to lists:flatten (in a fun()), then how 
could that be changed without recompilation? Were you thinking that 
?LAZY would be something like

        case yxa_config:get_env(debug_log_enabled) of
            true  -> fun() -> A() end;
            false -> []

Anyway, this scheme making it possible to actually eliminate lots of 
code whose purpose is just to create debug log messages are probably 
something that has to come one day or another. This hidden cost is what
I meant with the cost of debug logging probably being even higher than 10%.

> The logger:log/3 function would then do:
> log(A, B, F) when is_function(F) ->
>      log(A, B, F());
> log(A, B, C) ->
>      ...
> What do you think?

It's a good idea to increase performance, even if an even better 
solution would be if computers could just get faster so that we didn't 
have to care about performance =).

Seriously, what I would like to do is to release YXA 1.0 before making 
this change (I'm just waiting for a new edoc), and then do some 
measurements on the performance gained by ?LAZY just to make sure it is 
worthwhile, and then do it. If YXA 1.0 can be correct, then 1.5 or 
something could be both fast and correct =). Is this acceptable?


PS. The really _really_ good solution would be one that made it possible 
to evaluate if a transaction should get debug logging or not at runtime, 
so that one could enable debug logging for a specific peer when needed. 
I don't know if that is ever going to be possible with lazy creation of 
log data though. I've tried creating such functionality before by 
letting the logger process look at the group leader for whatever process 
generates a log message, and then see if the group leader has been 
flagged for debug logging or not, but never got it working...
Yxa-devel mailing list

Reply via email to