March 06, 2012
On Mar 6, 2012, at 11:59 AM, Jose Armando Garcia wrote:
> 
> Future:
> 
> 1. Allowing filtering of regular log messages (like info, warning,
> etc) based on the module. Similar to how vlog works.
> 2. Add support for custom line formatters
> 3. Talk about adding config.setSeverity(...) which is a union of all
> the severity specified. The logical OR operator is not going to work
> because internally the values are 0,1, etc. and we use them to index
> into an array. One solution is to pass an array to
> config.setSeverity(…)

For future enhancements, I'd just reference the docs for Boost.Log :-p
March 06, 2012
On Mar 6, 2012, at 11:39 AM, Jose Armando Garcia wrote:

> Seriously everyone. What are we spending some much effort on this? What is wrong with:
> 
> import log = std.log;
> log.info("cool");

Why should the default be unqualified names?  Is this simply a desire to not change std.log so we can just get it in already?
March 06, 2012
On Tue, 6 Mar 2012, Jose Armando Garcia wrote:

> Future:
> 
> 1. Allowing filtering of regular log messages (like info, warning, etc) based on the module. Similar to how vlog works.

Once you add module filtering to the regularly log messages, what's the point of having the separate vlog?  I think this needs to be figured out before merge, not at some vague future.

> Fix now:
> 
> 1. Add thread name attribute to the default logger
> 2. Check that the example compile
> 3. Come up with a better name for Rich and rich template
> 4. Add @safe pure nothrow const to as many methods as possible
> 5. Remove check when setting Configuration.logger

I still believe pretty strongly that the logger must not affect application flow, ie, not throw or exit the app.  From the feed back, I am not alone in thinking that.  I don't believe that "well, don't use those log levels" is a workaround if for no other reason that there will be libraries that contain them and that becomes a "dont use those libraries either" response.

My 2 cents,
Brad

March 06, 2012
On Tue, Mar 6, 2012 at 12:43 PM, Sean Kelly <sean@invisibleduck.org> wrote:
> On Mar 6, 2012, at 11:39 AM, Jose Armando Garcia wrote:
>
>> Seriously everyone. What are we spending some much effort on this? What is wrong with:
>>
>> import log = std.log;
>> log.info("cool");
>
> Why should the default be unqualified names?  Is this simply a desire to not change std.log so we can just get it in already?

What are you proposing?

struct Log {
  static alias log!Severity.info info;
  ...
}

I am not exactly sure when this idiom became popular. I don't know if this is an C++ idiom or a Java idiom but I do know that it is a broken hack. C++ developers use it because the name-spacing facility is limiting. Java uses it because everything is a class and they don't have the concept of compile time objects. We don't need this hack in D. D's module mechanism make this C++/Java idiom unnecessary.


Thanks,
-Jose
March 06, 2012
On Tue, Mar 6, 2012 at 1:08 PM, Brad Roberts <braddr@puremagic.com> wrote:
> On Tue, 6 Mar 2012, Jose Armando Garcia wrote:
>
>> Future:
>>
>> 1. Allowing filtering of regular log messages (like info, warning, etc) based on the module. Similar to how vlog works.
>
> Once you add module filtering to the regularly log messages, what's the point of having the separate vlog?  I think this needs to be figured out before merge, not at some vague future.
>

That is true the need for vlog is lessen from a configuration point of view but not from a performance point of view.

Adding module filtering to info, warning, etc increases the computational cost of determining if you should log. Right now that computational cost is constant. It is equal to a comparison operation. If you want module base filtering the computational complexity will probably be O(n + l) where n is the number of modules/entry in the filter and l is the minimum between the length of the module/file name and the length of the filters.

This makes info, warning, error a great tool to use in production across your program. While you can use vlog on a case by case basis in testing environments.

Thanks,
-Jose

>> Fix now:
>>
>> 1. Add thread name attribute to the default logger
>> 2. Check that the example compile
>> 3. Come up with a better name for Rich and rich template
>> 4. Add @safe pure nothrow const to as many methods as possible
>> 5. Remove check when setting Configuration.logger
>
> I still believe pretty strongly that the logger must not affect application flow, ie, not throw or exit the app.  From the feed back, I am not alone in thinking that.  I don't believe that "well, don't use those log levels" is a workaround if for no other reason that there will be libraries that contain them and that becomes a "dont use those libraries either" response.
>
> My 2 cents,
> Brad
>
March 06, 2012
On Tue, 06 Mar 2012 13:41:32 -0600, Jose Armando Garcia <jsancio@gmail.com> wrote:
> On Tue, Mar 6, 2012 at 10:11 AM, Robert Jacques <sandford@jhu.edu> wrote:
>> On Tue, 06 Mar 2012 11:44:13 -0600, Jose Armando Garcia <jsancio@gmail.com>
>> wrote:
>>>
>>> On Tue, Mar 6, 2012 at 9:32 AM, Robert Jacques <sandford@jhu.edu> wrote:
>>>>
>>>> On Tue, 06 Mar 2012 11:01:19 -0600, Jose Armando Garcia
>>>> <jsancio@gmail.com>
>>>> wrote:
>>>>
>>>>> On Wed, Feb 29, 2012 at 4:13 PM, Richard van Scheijen <dlang@mesadu.net>
>>>>> wrote:
>>>>>>
>>>>>>
>>>>>> When logging the severity level should convey a certain insight that
>>>>>> the
>>>>>> developer has about the code. This can be done with a 3 bit field.
>>>>>> These
>>>>>> are: known-cause, known-effect and breaks-flow.
>>>>>>
>>>>>> This creates the following matrix:
>>>>>>
>>>>>> KC KE BF Severity
>>>>>> =================
>>>>>> 1  1  0  Trace
>>>>>> 0  1  0  Info
>>>>>> 1  0  0  Notice
>>>>>> 0  0  0  Warning
>>>>>> 1  1  1  Error
>>>>>> 0  1  1  Critical
>>>>>> 1  0  1  Severe
>>>>>> 0  0  1  Fatal
>>>>>>
>>>>>> A known cause is when the developer knows why a log event is made.
>>>>>> e.g.:
>>>>>> if
>>>>>> you cannot open a file, you do not know why.
>>>>>> A known effect is when he/she knows what happens after. Basically, you
>>>>>> can
>>>>>> tell if it is a catch-all by this flag.
>>>>>>
>>>>>> When a severity should only be handled by a debugger, the normal debug
>>>>>> statement should be used. This is in essence a 4th bit.
>>>>>>
>>>>>> I hope this helpful in the search for a good level system.
>>>>>>
>>>>>
>>>>> Interesting observation on logging. I like your theoretical
>>>>> observation and explanation. To me the most important thing is
>>>>> usability and unfortunately people are used to log levels as a order
>>>>> concept. Meaning error is higher severity than info so if I am logging
>>>>> info events I should probably also log error events.
>>>>>
>>>>> If we go with a mechanism like the one you describe above there is no
>>>>> order so the configuration is a little more complicated or verbose I
>>>>> should say. Instead of saying we should log everything "greater" than
>>>>> warning the user needs to say that they want to log known-cause,
>>>>> known-effect, breaks-flow events. This mean that there are 27 (= 3^3)
>>>>> configuration combinations. To implement this we need 3 configuration
>>>>> nobs with 3 values (on, off, both).
>>>>>
>>>>> Thoughts?
>>>>> -Jose
>>>>
>>>>
>>>>
>>>> There are only 8 possible configurations and they are nicely ordered in
>>>> terms of severity. So I don't see this as a problem. Also, if you went
>>>> with
>>>> a combinatorial approach, shouldn't it be 2^8 = 256, not 3^3 = 27 values?
>>>
>>>
>>> Yes. If you want to enable and disable each individual "level" then
>>> you need 8 configuration options which leads to 2^8.
>>>
>>> I suggested 3^3 as a more reasonable options that matches how the
>>> developer is logging but doesn't give you as much expressiveness as
>>> the 2^8 option.
>>
>>
>> In practice, all you'd need to take is a flag with the desired levels. i.e.
>>
>> // Automatically set logging levels using the standard severity ordering
>> config.minSeverity(Severity.Warning);
>>
>> // Manually set the logging levels
>> config.setSeverities(Severity.Warning|
>>                     Severity.Error|
>>                     Severity.Critical|
>>                     Severity.Severe|
>>                     Severity.Fatal);
>>
>> I don't see the problem with including both methods and a large advantage to
>> having a standardized severity framework.
>
> Interesting. If you find this useful, I think we can add this in a
> future release as it shouldn't break existing modules that maybe using
> the library.

This began as a discussion regarding Richard's organization of logging severity. That organization isn't something that can be trivially included at a later date.
March 06, 2012
On Tue, 06 Mar 2012 13:32:37 -0600, Jose Armando Garcia <jsancio@gmail.com> wrote:

> On Mon, Mar 5, 2012 at 5:30 PM, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>> On Mon, 05 Mar 2012 20:22:05 -0500, so <so@so.so> wrote:
>>
>>> On Monday, 5 March 2012 at 23:51:29 UTC, Steven Schveighoffer wrote:
>>>>
>>>> On Mon, 05 Mar 2012 18:30:03 -0500, David Nadlinger <see@klickverbot.at>
>>>> wrote:
>>>>
>>>>> On Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrote:
>>>>>>
>>>>>> The log aliases use names that are too common.  I think log.info is a
>>>>>> better symbol for logging than just 'info', which could be a symbol in a
>>>>>> myriad of places.  Given that D's symbol lookup rules allow shadowing of
>>>>>> global symbols, this does not work out very well.
>>>>>
>>>>>
>>>>> Originally, the code used log!info and so on, but it was changed to the
>>>>> current design right after review begin, the rationale being that you could
>>>>> always use »import log = std.log« if you want the extra namespace.
>>>>
>>>>
>>>> That doesn't help.  Software isn't static.
>>>>
>>>> import std.log;
>>>> import other; // defines B
>>>>
>>>> class A : B
>>>> {
>>>>   void foo()
>>>>   {
>>>>      info("some info message"); // error! int isn't a function!
>>>>   }
>>>> }
>>>>
>>>> other.d:
>>>>
>>>> class B
>>>> {
>>>>   int info; // added later
>>>> }
>>>
>>>
>>> That is not a counter-argument to something related to this library but
>>> everything that lies in global namespace.
>>> At its first state both severity levels and the "log" was in global
>>> namespace. Now only severity levels.
>>>
>>> You are also overlooking one crucial fact that this library will be part
>>> of phobos, standard library. Which requires everyone to adopt. When you see
>>> codes like this (below), you don't blame standard library designers do you?
>>>
>>> using namespace std;
>>> int cout;
>>
>>
>> Except 'info', 'error', 'warning' are all common names, likely to be a very
>> attractive name for something that has nothing to do with (or cares about)
>> logging.  cout is not a common name or even an english word, so it's
>> unlikely someone has or wants to create a cout member.
>>
> Actually, I see this more as argument as to why cout is a horrible
> name for a symbol in std.stdio. I suspect that the only reason that it
> is there is to keep C developer migrating to D happy. It should
> probably just be "out" like Java (System.out) and C# (Console.Out).

D doesn't have a cout, in stdio or elsewhere.
March 06, 2012
On Tue, Mar 6, 2012 at 1:08 PM, Brad Roberts <braddr@puremagic.com> wrote:
> On Tue, 6 Mar 2012, Jose Armando Garcia wrote:
>
>> Future:
>>
>> 1. Allowing filtering of regular log messages (like info, warning, etc) based on the module. Similar to how vlog works.
>
> Once you add module filtering to the regularly log messages, what's the point of having the separate vlog?  I think this needs to be figured out before merge, not at some vague future.
>
>> Fix now:
>>
>> 1. Add thread name attribute to the default logger
>> 2. Check that the example compile
>> 3. Come up with a better name for Rich and rich template
>> 4. Add @safe pure nothrow const to as many methods as possible
>> 5. Remove check when setting Configuration.logger
>
> I still believe pretty strongly that the logger must not affect application flow, ie, not throw or exit the app.  From the feed back, I am not alone in thinking that.  I don't believe that "well, don't use those log levels" is a workaround if for no other reason that there will be libraries that contain them and that becomes a "dont use those libraries either" response.
>

Yeah. I completely understand your point. I don't have a technical argument for adding or removing fatal and critical. The only advantage is that the developer is explicitly telling the logging framework when the application will/may terminate. Instead of everyone having to write:

void critical(...) {
  log.error(...);
  // force a flush. currently there is no way of expressing this so we
need to put this
  throw new ...;
}

and:

void fatal(...) {
  log.error(...);
  // force a flush. currently there is no way of expressing this so we
need to put this
  assert(true);
}

> My 2 cents,
> Brad
>
March 06, 2012
I still don't understand how to set the filename of the log file. Has this been added yet?
March 06, 2012
On Tue, Mar 6, 2012 at 2:44 PM, Andrej Mitrovic <andrej.mitrovich@gmail.com> wrote:
> I still don't understand how to set the filename of the log file. Has this been added yet?

http://jsancio.github.com/phobos/phobos/std_log.html#fileNamePrefixes