Early review of std.logger

ilya-stromberg ilya-stromberg-2009 at yandex.ru
Tue Oct 15 07:17:34 PDT 2013


On Tuesday, 15 October 2013 at 14:12:38 UTC, Sönke Ludwig wrote:
> Am 15.10.2013 15:52, schrieb Robert Schadek:
>> On 10/15/2013 03:21 PM, Sönke Ludwig wrote:
>>> Am 15.10.2013 10:41, schrieb Robert Schadek:
>>>> On 10/15/2013 02:44 AM, Kapps wrote:
>>>>> The simple act of logging a message is very verbose right 
>>>>> now:
>>>>> log(LogLevel.trace, "Creating new pool") is a lot of boiler 
>>>>> plate. I'd
>>>>> prefer something like log.trace("Creating new pool") and 
>>>>> log("Creating
>>>>> new pool") where the latter would use opCall to forward to 
>>>>> the default
>>>>> log level. If it's intentional that you can assign the 
>>>>> result of log,
>>>>> this also helps that because log = new StdIOLogger would be 
>>>>> possible
>>>>> (log being a property that returns a Logger, and so a 
>>>>> setter could be
>>>>> made), but log("Creating new pool") = new StdIOLogger() 
>>>>> would not be.
>>>> The LogLevel is optional. And always writing log.trace might 
>>>> become more
>>>> typing work and assigning a LogLevel and than calling 
>>>> log("..."). Both
>>>> have pros and cons
>>>
>>> What happens when a called function alters the default log 
>>> level?
>> The default log level is altered.
>
> Believe it or not, for some reason I suspected as much.
>
>>>
>>> ---
>>> void func1() {
>>>     log.logLevel = LogLevel.debug;
>>>     log("This is a debug message");
>>>     func2();
>>>     log("This is supposed to be a debug message");
>>> }
>>>
>>> void func2() {
>>>     log.logLevel = LogLevel.warning;
>>>     log("This is a warning");
>>> }
>>> ---
>> If you don't specify a logger nor a LogLevel the currently set 
>> default
>> logger will log the message with its currently set LogLevel.
>
> Yes, but the point is that when looking only at func1, you 
> might expect that all messages are logged as debug messages, 
> but the last one will be logged as a warning instead. func2 may 
> be hidden in library where the function body is not readily 
> available.
>
>>>
>>>
>>> I don't think it's a good idea to use such kind of global 
>>> state,
>>> especially for a logging framework that is supposed to be 
>>> shared
>>> between libraries, so that it is difficult to predict what a
>>> particular function does. With a logger that is shared between
>>> threads, things get worse of course.
>> I think this is good, as it gives you a way to quite libraries 
>> down. The
>> idea behind the free standing "log" function is to provide an 
>> ultra easy
>> way to log. It is not meant to be used for the 2<<31 line 
>> program. In
>> that case you will properly have very specific needs on how to 
>> log.
>> Hence implement the abstract Logger class to your needs.
>
> But if it's available people _will_ use it in complex contexts. 
> Also if the writer of a 2<<8 loc library uses it and the 
> library is used by a large piece of software, that will also be 
> affected. The point is that it is unhygienic and requires 
> non-trivial extra work when using a logger in a multi-threaded 
> environment. Some kind of scoped stack of default log levels 
> would get around this issue, but that smells like over 
> engineering.

+1
I dislike syntax:
log.logLevel = LogLevel.warning;
log("This is a warning");

Much better:
log.warning("This is a warning");


More information about the Digitalmars-d mailing list