[erlang-questions] Logging methods in Erlang (FUNCTION macro)
Michael Truog
mjtruog@REDACTED
Sat Sep 6 02:04:49 CEST 2014
On 09/05/2014 03:41 PM, Loïc Hoguin wrote:
> On 09/05/2014 11:25 PM, Michael Truog wrote:
>> When you care about the efficiency of logging within Erlang source code
>> (i.e., only using Erlang source code for a logging solution) there are
>> two main solutions:
>>
>> 1) Dynamically compile a module based on the logging level that is
>> currently set and reload it. Lower log levels are naturally ignored
>> because their function doesn't do anything within the updated module.
>> This was done in older versions of ejabberd
>> (https://github.com/processone/ejabberd/blob/2.1.x/src/ejabberd_loglevel.erl),
>> but ejabberd has since switched to using lager. CloudI uses this
>> approach
>> (https://github.com/CloudI/CloudI/blob/develop/src/lib/cloudi_core/src/cloudi_core_i_logger.erl).
>
> I like this approach. I do not know how you use it but I hope you don't have to type cloudi_core_i_logger:log(...) everytime you want to log something.
There is a header file with macros to provide MODULE and LINE at the line where the logging statement is, in addition to macros that allow you to call erlang:apply/2 or erlang:apply/3 based on the current logging level (https://github.com/CloudI/CloudI/blob/develop/src/lib/cloudi_core/include/cloudi_logger.hrl). So, a macro call like ?LOG_ERROR("This is an error with data: ~p", [Date]), will work as expected. Elixir requires the macros be in a module, but the module is in the same include directory to make it easy to utilize (https://github.com/CloudI/CloudI/blob/develop/src/lib/cloudi_core/include/CloudILogger.ex).
>
>> 2) Use a parse transform to rewrite all the source code that wants to do
>> logging so that it can determine whether it needs to log by checking
>> global state, probably in ets. This approach is taken in lager with the
>> parse transform at
>> https://github.com/basho/lager/blob/master/src/lager_transform.erl .
>
> I do not like this one, especially since lager will simply fail if modules were not compiled with the parse_transform (the functions aren't defined). So you have to compile everything with it, can't call from the shell (at least not the same way), yada yada. Very impractical. Efficiency is always good to have but that one is quite costy.
>
> [...]
>> However, it is much better if we can avoid any overhead when getting the
>> current function name. That means it would be best to have a FUNCTION
>> preprocessor macro available within Erlang source code. Is there any
>> clear reason why this should not be done?
>
> I think we should *definitely* have a ?FUNCTION macro.
>
> The main problem I can see with such a macro however is that the preprocessor would need some knowledge of Erlang syntax, which it probably doesn't have today. But I do not think it is impossible considering the advantages a ?FUNCTION would give.
>
More information about the erlang-questions
mailing list