digitalmars.D - Review of Jose Armando Garcia Sancio's std.log
- David Nadlinger (24/24) Feb 13 2012 There are several modules in the review queue right now, and to get
- David Nadlinger (31/33) Feb 13 2012 A few small points from a first pass through the docs:
- Jonathan M Davis (7/10) Feb 13 2012 syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) as the w...
- Andrej Mitrovic (1/1) Feb 13 2012 I'd like to see a simple example of how to specify the filename of the l...
- Jose Armando Garcia (27/62) Feb 13 2012 d3cc8e6f5
- Jose Armando Garcia (23/33) Feb 13 2012 akest.
- HeiHon (19/41) Feb 16 2012 In my applications I want my logs to be human readable by users
- Jose Armando Garcia (3/4) Feb 13 2012 Fair enough...
- jdrewsen (7/7) Feb 13 2012 A first quick observation:
- Sean Kelly (4/11) Feb 13 2012 I think that's what vlog is for, it just isn't particularly well =
- Jose Armando Garcia (2/11) Feb 13 2012 I agree. Let me know how I can improve this...
- Jose Armando Garcia (4/11) Feb 13 2012 I like the idea of having a default. Not sure about adding debug. What
- Andrei Alexandrescu (4/19) Feb 13 2012 Let's not forget we could always do
- jdrewsen (10/29) Feb 14 2012 As Sean mentioned the vlog function may be the one I want. Maybe
- Jose Armando Garcia (3/28) Feb 14 2012 If we do set a default what should it be? It is not clear to me what
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (19/19) Feb 13 2012 Log levels "debug" and maybe also "trace" would be useful, but I see
- James Miller (30/48) Feb 13 2012 ly
- Jose Armando Garcia (18/36) Feb 13 2012 ly
- Jose Armando Garcia (19/68) Feb 13 2012 nly
- Jacob Carlborg (4/23) Feb 13 2012 --
- Jose Armando Garcia (11/39) Feb 14 2012 What do you mean by formatter? For example the default Logger
- Jacob Carlborg (4/36) Feb 14 2012 Yeah, I was referring to something like outputting HTML. Ok, I see.
- so (14/41) Feb 13 2012 Good work.
- Jose Armando Garcia (4/49) Feb 13 2012 I like it! I think I tried this before but I thought "compiled time"
- Jacob Carlborg (8/55) Feb 13 2012 It would then be possible to use renamed imports to have something like
- Jonathan M Davis (5/35) Feb 13 2012 Personally, I'd just copy what syslog does in terms of log levels. Then
- Jose Armando Garcia (12/47) Feb 13 2012 t
- Jonathan M Davis (31/77) Feb 13 2012 om>=20
- Johannes Pfau (4/7) Feb 14 2012 Right now. But once systemd took over the world:
- Andrei Alexandrescu (30/33) Feb 13 2012 Thanks Jose and David. I made a pass, here are a few thoughts:
- Jose Armando Garcia (33/67) Feb 14 2012 Fixed all of the above comments.
- jdrewsen (4/31) Feb 14 2012 Updated wiki: http://prowiki.org/wiki4d/wiki.cgi?ReviewQueue
- Jacob Carlborg (5/29) Feb 14 2012 Is it possible to log to other locations, i.e. to the standard location
- David Nadlinger (7/9) Feb 14 2012 While the current proposal only includes a file backend, my
- Jacob Carlborg (5/14) Feb 14 2012 Ok, I see. I don't think it would be necessary with different backends,
- Jose Armando Garcia (14/53) Feb 14 2012 What do you mean by location? If you mean file system directory then:
- Jacob Carlborg (6/58) Feb 14 2012 I meant something like a general interface one could implement to be
- Jose Armando Garcia (17/41) Feb 14 2012 s
- jdrewsen (5/31) Feb 14 2012 In the introduction text the references to Configuration etc.
- Jose Armando Garcia (4/37) Feb 14 2012 ade
- jdrewsen (7/53) Feb 14 2012 For example: $(LREF Configuration)
- Jose Armando Garcia (11/35) Feb 14 2012 s
- bls (3/8) Feb 12 2012 This is somehow bad. Review a piece of library-software by using a beta
- so (3/5) Feb 15 2012 Indeed, never happened such thing in whole compiler/language
- David Nadlinger (4/6) Feb 15 2012 I don't quite see where the problem is with that. Besides, 2.058
- Jonathan M Davis (36/39) Feb 16 2012 Why does vlog even exist? It's a needless complication IMHO. Let the log...
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (17/56) Feb 16 2012 Well in addition to Debug I would also like to see Trace but it's f. ex....
- Jacob Carlborg (5/47) Feb 16 2012 I think this is way too many levels. Why not just define few levels
- Jonathan Stephens (12/14) Feb 16 2012 - CRIT - the application cannot continue
- =?UTF-8?B?U8O2bmtlIEx1ZHdpZw==?= (2/14) Feb 17 2012 Thats also exactly my experience (and what I use).
- H. S. Teoh (26/41) Feb 16 2012 correctly. Most people, sadly to say, can't be bothered to read the
- David Nadlinger (5/13) Feb 18 2012 I think avoiding this problem is one of the major benefits of the
- Jose Armando Garcia (36/114) Feb 17 2012 y
- Andrei Alexandrescu (3/4) Feb 17 2012 I think defaulting to formatted stuff may be confusing.
- Jose Armando Garcia (13/19) Feb 17 2012 Even if we document this? I mean:
- =?ISO-8859-1?Q?S=F6nke_Ludwig?= (9/13) Mar 03 2012 Do you often log static messages? In my experience the majority of
- Andrei Alexandrescu (10/25) Mar 03 2012 I think it's fine to default to formatted. Also, it just occurred to me
- Dmitry Olshansky (10/36) Mar 04 2012 I would say just separate them please. Let it work as writeln/writefln
- Andrei Alexandrescu (3/10) Mar 04 2012 Yah, agreed. Probably calls with no extra arguments should be safe.
- Jose Armando Garcia (63/104) Feb 17 2012 e
- Walter Bright (8/10) Feb 17 2012 This is a general comment, not specific to std.log:
- Jose Armando Garcia (5/18) Feb 17 2012 Yep. I have been following that thread and your commits. I have a TODO f...
- Kalle Svensson (11/11) Feb 27 2012 Since I'm D n00b I'll just post a couple of observations:
- Mikael Lindsten (6/17) Mar 01 2012 I second what Kalle Svensson is saying.
- H. S. Teoh (15/21) Mar 01 2012 [...]
- Jose Armando Garcia (13/34) Mar 06 2012 Agreed. I have recently extended this to hierarchy. Most of the time
- Jose Armando Garcia (4/15) Mar 06 2012 I agree but I am some what hesitant to add this now as it will just
- Richard van Scheijen (21/21) Feb 29 2012 When logging the severity level should convey a certain insight
- Sean Kelly (25/44) Mar 01 2012 the developer has about the code. This can be done with a 3 bit field. =
- Robert Jacques (4/25) Mar 01 2012 vote++
- H. S. Teoh (5/43) Mar 02 2012 +1. I like this *much* better than "info", "notice", ... etc.
- mist (6/8) Mar 03 2012 Simply defining log level enum in terms of this bit field would
- Jose Armando Garcia (9/43) Mar 06 2012 p
- Robert Jacques (6/53) Mar 06 2012 The corollary to this is that causation is not clear from order. As I
- Jose Armando Garcia (18/39) Mar 06 2012 if
- Robert Jacques (6/51) Mar 06 2012 There are only 8 possible configurations and they are nicely ordered in ...
- Jose Armando Garcia (12/66) Mar 06 2012 e
- Robert Jacques (13/83) Mar 06 2012 In practice, all you'd need to take is a flag with the desired levels. i...
- Jose Armando Garcia (12/100) Mar 06 2012 t>
- Robert Jacques (5/112) Mar 06 2012 This began as a discussion regarding Richard's organization of logging
- Jose Armando Garcia (17/136) Mar 06 2012 :
- Robert Jacques (6/129) Mar 06 2012 Richard proposed an organizational framework for logging severity, which...
- Jose Armando Garcia (36/64) Mar 06 2012 developer has about the code. This can be done with a 3 bit field. Thes...
- kennytm (12/38) Mar 07 2012 Minor nit: if you rearrange it as
- Brad Roberts (21/46) Mar 02 2012 My 2 cents from a fairly quick scan of the docs:
- Steven Schveighoffer (24/28) Mar 05 2012 Some notes:
- David Nadlinger (16/28) Mar 05 2012 Originally, the code used log!info and so on, but it was changed
-
Steven Schveighoffer
(32/47)
Mar 05 2012
On Mon, 05 Mar 2012 18:30:03 -0500, David Nadlinger
... - so (12/41) Mar 05 2012 That is not a counter-argument to something related to this
- Steven Schveighoffer (23/67) Mar 05 2012 =
- so (6/17) Mar 05 2012 I have no objections against changing names. For example, instead
- Jose Armando Garcia (18/80) Mar 06 2012 a
- Robert Jacques (14/90) Mar 06 2012 e:
- Steven Schveighoffer (9/23) Mar 07 2012 Like Robert says, cout is not in std.stdio. (maybe you were thinking of ...
- Jonathan M Davis (8/20) Mar 05 2012 Except that cout is not exactly something that would be considered a nor...
- so (3/5) Mar 05 2012 Now you got not only "info" but "log" in global namespace :)
- Jacob Carlborg (4/24) Mar 05 2012 The user can then alias "log!info" to "info" if he/she wants to.
- Jonathan M Davis (5/31) Mar 05 2012 The user can do whatever aliases they want. It's just that we shouldn't
- Jacob Carlborg (5/36) Mar 06 2012 What I'm trying so say is that if we use the template function the user
- so (4/6) Mar 06 2012 Again, you are now forcing 2 common names instead of one as it is
- Jonathan M Davis (6/14) Mar 06 2012 Yes. My mistake - probably because the time stuff typicall takes such a
- Jose Armando Garcia (7/21) Mar 06 2012 Seriously everyone. What are we spending some much effort on this?
- Andrei Alexandrescu (4/8) Mar 06 2012 Indeed I think that should be fine.
- H. S. Teoh (6/14) Mar 06 2012 [...]
- Steven Schveighoffer (9/32) Mar 07 2012 Because naming is important. It's very difficult to change names once
- Steven Schveighoffer (9/41) Mar 07 2012 alternatively:
- Jose Armando Garcia (8/59) Mar 11 2012 a
- Steven Schveighoffer (26/48) Mar 12 2012 I'm against having a requirement (or at least a strong suggestion) to
- Sean Kelly (2/19) Mar 11 2012 Which is the more common case?
- Sean Kelly (3/8) Mar 06 2012 Why should the default be unqualified names? Is this simply a desire to...
- Jose Armando Garcia (15/22) Mar 06 2012 o not change std.log so we can just get it in already?
- Sean Kelly (5/33) Mar 06 2012 Sorry. For some reason I thought info was callable directly without the ...
- Robert Jacques (2/46) Mar 05 2012 Please don't forget that you are _submitting_ a library into Phobos and ...
- so (3/7) Mar 06 2012 Probably it is the reason why they use cryptic variable names in
- Jose Armando Garcia (10/66) Mar 06 2012 Not is doesn't. First, it will only break your code if you import
- Andrei Alexandrescu (4/5) Mar 06 2012 I think this works better:
- David Nadlinger (5/9) Mar 06 2012 Isn't this just another case of DMD silently accepting
- Jose Armando Garcia (9/29) Mar 06 2012 using namesapce std;
- Steven Schveighoffer (7/40) Mar 07 2012 The not so trivial and important difference is here:
- Jose Armando Garcia (12/54) Mar 06 2012 a
- Jose Armando Garcia (36/64) Mar 06 2012 gs
- Steven Schveighoffer (49/118) Mar 07 2012 Then I can't access the fatal level.
- Jose Armando Garcia (47/93) Mar 06 2012 riod starts now and ends in three weeks, on
- Jose Armando Garcia (33/57) Mar 06 2012 s
- Sean Kelly (2/13) Mar 06 2012 For future enhancements, I'd just reference the docs for Boost.Log :-p=
- Brad Roberts (12/23) Mar 06 2012 Once you add module filtering to the regularly log messages, what's the
- Jose Armando Garcia (18/41) Mar 06 2012 That is true the need for vlog is lessen from a configuration point of
- Jose Armando Garcia (22/45) Mar 06 2012 am
- Andrej Mitrovic (2/2) Mar 06 2012 I still don't understand how to set the filename of the log file. Has
- Jose Armando Garcia (3/5) Mar 06 2012 http://jsancio.github.com/phobos/phobos/std_log.html#fileNamePrefixes
- Andrej Mitrovic (5/6) Mar 06 2012 That was what I was looking for but I didn't find it at first. I think
- Jose Armando Garcia (23/41) Mar 06 2012 ut
- Jose Armando Garcia (12/18) Mar 06 2012 Yeah. I am not terribly happy how ddoc and dlang.org organizes the
- Jonathan M Davis (3/27) Mar 06 2012 Agreed. The logging functions should _not_ throw.
- Geoffrey Biggs (12/29) Mar 06 2012 +1.
- Andrei Alexandrescu (15/44) Mar 06 2012 I don't see why the agitation around this particular matter. It's a
- Jonathan M Davis (13/30) Mar 06 2012 I think that it would be far more meaningful to have a logging function ...
- Andrei Alexandrescu (4/6) Mar 06 2012 Throwing an exception is not error handling. If it were, so many
- Geoffrey Biggs (15/28) Mar 06 2012 That approach means that if I actually do have a fatal error, I can't
- Andrei Alexandrescu (3/5) Mar 06 2012 Use log.fatal for those.
- Robert Jacques (8/13) Mar 07 2012 But fatal "Logs a fatal severity message. Fatal log messages terminate t...
- Jose Armando Garcia (13/30) Mar 11 2012 Okay. Let me say this one last time. If you don't want to assert or
- Robert Jacques (2/35) Mar 12 2012 There is a strong impression that a 'fatal' error and an 'error' will ap...
- Jose Armando Garcia (3/55) Mar 12 2012 Okay. Let me try to wipe something up soonish but it may take me some
- Jose Armando Garcia (6/39) Mar 06 2012 Fatal and Critical severity cannot be disabled either at runtime or at
- Jose Armando Garcia (12/43) Mar 06 2012 This exactly how I am thinking of extending critical. I don't have an
- Geoffrey Biggs (6/27) Mar 06 2012 OK, I took another look at the docs. I see your point now. Sorry for
- Steven Schveighoffer (12/61) Mar 07 2012 I think access to the fatal/critical logging level should not be coupled...
- Jose Armando Garcia (13/86) Mar 11 2012 se
- H. S. Teoh (51/69) Mar 06 2012 [...]
- David Gileadi (3/49) Mar 07 2012 I strongly agree, particularly in the case of ranges which are not a
- H. S. Teoh (19/28) Mar 06 2012 [...]
- Jonathan M Davis (10/13) Mar 06 2012 No, because they affect the log level. The concept of throwing and the l...
- Andrei Alexandrescu (9/23) Mar 06 2012 Why?
- Jonathan M Davis (21/36) Mar 06 2012 Because the level that you log something at and what you want to do in t...
- Andrei Alexandrescu (12/38) Mar 06 2012 Then I guess you'd be well advised to use the function that "logs to the...
- Jonathan M Davis (13/46) Mar 06 2012 Sure, but std.log appears to have built in whether an exception is throw...
- Steven Schveighoffer (11/29) Mar 07 2012 As has been repeatedly pointed out, the fatal and critical levels are
- James Miller (12/48) Mar 06 2012 Surprisingly, I agree with the idea that fatal and critical shouldn't
- Dmitry Olshansky (5/58) Mar 06 2012 Exception is a graceful shutdown, as it calls destructors & finally
- Steven Schveighoffer (6/8) Mar 07 2012 You're assuming the program uses finally/scope exit blocks to do shutdow...
- Dmitry Olshansky (10/17) Mar 07 2012 I do and within the reason. Doing graceful shutdown logic in
- Steven Schveighoffer (13/19) Mar 07 2012 I see this pattern emerging:
- Jose Armando Garcia (10/30) Mar 11 2012 Or you can just:
- Jonathan M Davis (4/6) Mar 06 2012 It _is_ callable that way. Just look at the example at the top:
- David Nadlinger (13/15) Mar 07 2012 Okay, everyone, by the original schedule, the review period would
- Jose Armando Garcia (3/17) Mar 07 2012 Thanks David! I will have to some time later today to answer some of
- David Nadlinger (4/4) Mar 11 2012 Unfortunately, the discussion has ground to a halt again, so
- Robert Jacques (2/6) Mar 11 2012 Has Jose updated anything?
- David Nadlinger (5/6) Mar 11 2012 Not sure what you mean – the latest state of the code is at
- Robert Jacques (2/8) Mar 11 2012 There was a bunch of discussions/suggestions and then silence from Jose....
- Andrei Alexandrescu (12/16) Mar 11 2012 I thought more about the point made about mixing throwing and logging
- H. S. Teoh (8/20) Mar 11 2012 [...]
- Jose Armando Garcia (36/54) Mar 11 2012 g
- Steven Schveighoffer (4/20) Mar 12 2012 This is fine, since we can always add more levels later if a need arises...
- David Nadlinger (9/21) Mar 12 2012 Okay, so let's remove std.log from the review queue without a
- Andrei Alexandrescu (8/22) Mar 12 2012 I think that's a wise decision, thanks Jose and David.
- Jose Armando Garcia (8/35) Mar 12 2012 I have tried to document every major modification that the community
- James Miller (7/22) Mar 12 2012 Jose, I haven't used Trello, but is it possible to open up this board
- Jose Armando Garcia (5/31) Mar 12 2012 I don't think I have access to do that in Trello. Anyone? Post you
- Geoffrey Biggs (12/30) Mar 12 2012 levels. I agree that it's awkward to e.g. log to critical without =
There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! David
Feb 13 2012
On 2/13/12 4:50 PM, David Nadlinger wrote:https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.htmlA few small points from a first pass through the docs: Spelling nits: - potion -> position - enviroment -> environment - arguements -> arguments - explictly -> explicitly - fileter -> filter - persiste -> persist - genereated -> generated - brakets -> brackets - paramater -> parameter - compuration -> computation The introductory section needs some copy editing, e.g.: - In the first paragraph, every sentence starts with »The module« - disabled/enabled -> disable/enable - »In the other« -> »in the order« You define the Severity enum members starting with fatal as 0. Why not the other way round – so that severityA < severityB would do what you (or at least I) would expect? Include a cross-reference to log() in the Severity comment? Maybe clarify the meaning of »can be logged« (i.e. the severity level is not completely disabled) in the LogFilter docs? Are the explicit to!string calls in the first LogFilter example required? config.logger: First line is missing a full stop, »The default value a FileLogger.«, »change and configure« (where is the difference?) »Create a configuration object based on the passed parameter.« is slightly misleading, because parseCommandLine() doesn't actually create an object. I'll post a more in-depth review later. David
Feb 13 2012
On Monday, February 13, 2012 17:49:49 David Nadlinger wrote:You define the Severity enum members starting with fatal as 0. Why not the other way round – so that severityA < severityB would do what you (or at least I) would expect?syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) as the weakest. The greater the number, the more logging output, you're going to see. So, he's following syslog in that respect, though he doesn't have as many log levels. He should probably add at least debug. He also aliases them to module-level symbols for some reason, which is a big no-no IMHO. - Jonathan M Davis
Feb 13 2012
I'd like to see a simple example of how to specify the filename of the log file.
Feb 13 2012
On Mon, Feb 13, 2012 at 2:49 PM, David Nadlinger <see klickverbot.at> wrote= :On 2/13/12 4:50 PM, David Nadlinger wrote:d3cc8e6f5https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cb=Thanks. I cleaned this up. I'll pass the rest through a spellchecker.Docs: http://jsancio.github.com/phobos/phobos/std_log.htmlA few small points from a first pass through the docs: Spelling nits: =A0- potion -> position =A0- enviroment -> environment =A0- arguements -> arguments =A0- explictly -> explicitly =A0- fileter -> filter =A0- persiste -> persist =A0- genereated -> generated =A0- brakets -> brackets =A0- paramater -> parameter =A0- compuration -> computationThe introductory section needs some copy editing, e.g.: =A0- In the first paragraph, every sentence starts with =BBThe module=AB =A0- disabled/enabled -> disable/enable =A0- =BBIn the other=AB -> =BBin the order=ABI fix it some what. Still not a big fan of the current introductory section. My current thinking for introductory section is to write something small that every developer should read. Probably something example driven. If they need details into how to configure the module then they can read the rest of the document. Thoughts?You define the Severity enum members starting with fatal as 0. Why not th=eother way round =96 so that severityA < severityB would do what you (or a=tleast I) would expect?Internally I wanted to use the same representation for severity as I would use for verbosity. I wanted 0 to represent the highest importance and increasing numbers to have lower severity/importance. This would allow users freely pick lower and lower verbose message as they develop their application without having to worry how the application is configured in the deployment/production environment.Include a cross-reference to log() in the Severity comment?DoneMaybe clarify the meaning of =BBcan be logged=AB (i.e. the severity level=is notcompletely disabled) in the LogFilter docs?Thanks. This part of the document was some what confusing. It should be a little better now.Are the explicit to!string calls in the first LogFilter example required? config.logger: First line is missing a full stop, =BBThe default value a FileLogger.=AB, =BBchange and configure=AB (where is the difference?)No, it is not. Fixed.=BBCreate a configuration object based on the passed parameter.=AB is sli=ghtlymisleading, because parseCommandLine() doesn't actually create an object.Good catch. Fixed. I have been thinking of changing the signature of the Configuration classes to look more like a builder by using the "with..." pattern in the method signature. Thoughts?I'll post a more in-depth review later. DavidThanks a lot. Your comments were helpful.
Feb 13 2012
On Mon, Feb 13, 2012 at 4:19 PM, Jonathan M Davis <jmdavisProg gmx.com> wro= te:On Monday, February 13, 2012 17:49:49 David Nadlinger wrote:akest.You define the Severity enum members starting with fatal as 0. Why not the other way round =96 so that severityA < severityB would do what you (or at least I) would expect?syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) as the we=The greater the number, the more logging output, you're going to see. So,=he'sfollowing syslog in that respect, though he doesn't have as many log leve=ls.He should probably add at least debug. He also aliases them to module-lev=elsymbols for some reason, which is a big no-no IMHO.I am trying to minimize the number of predefined log levels. One of the big problems I see with having too many log levels is that the programmer never knows which one to use. I think std.log makes this very clear: 1. Log at fatal if you want the application to assert 2. Log at critical if you want the thread to throw 3. Log at error if you detect a programming bug (invariant violation) but you wish to continue and cross your finger 4. Log at warning if you detected peculiar condition yet the program was coded to handle it. 5. Log at info if you want to document an action/state. 6. verbose log for trace/debugging specific parts of a program. I think it would help me that instead of suggesting another level we instead state what we think the user would like to do or log but the framework as defined doesn't let the user do. Thanks, -Jose- Jonathan M Davis
Feb 13 2012
On Tuesday, 14 February 2012 at 01:58:50 UTC, Jose Armando Garcia wrote:I am trying to minimize the number of predefined log levels. One of the big problems I see with having too many log levels is that the programmer never knows which one to use. I think std.log makes this very clear: 1. Log at fatal if you want the application to assert 2. Log at critical if you want the thread to throw 3. Log at error if you detect a programming bug (invariant violation) but you wish to continue and cross your finger 4. Log at warning if you detected peculiar condition yet the program was coded to handle it. 5. Log at info if you want to document an action/state. 6. verbose log for trace/debugging specific parts of a program. I think it would help me that instead of suggesting another level we instead state what we think the user would like to do or log but the framework as defined doesn't let the user do.In my applications I want my logs to be human readable by users and/or admins. I tend to have different kinds of what you call warnings. Say my app uploads a file by FTP. It would be something like: info("sending file to host") and then case a: info("file sent successfully - took time x") case b: warning("encountered some FTP problems") info("file sent successfully - took time x") case c: warning("encountered severe FTP problems - could not send file") The program can handle all three cases. But I want to clearly communicate to the user the different severity of the problems the program handled. BTW I normally call case c "error" (from the users perspective).
Feb 16 2012
On Mon, Feb 13, 2012 at 5:06 PM, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:I'd like to see a simple example of how to specify the filename of the log file.Fair enough...
Feb 13 2012
A first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message"); /Jonas
Feb 13 2012
On Feb 13, 2012, at 12:44 PM, jdrewsen wrote:A first quick observation: =20 I vote for a debug severity level. Then make that default to the =template parameter for log:=20 template log(Severity severity =3D Severity.debug) =20 That would make it nice for good old print debugging.I think that's what vlog is for, it just isn't particularly well = documented.=
Feb 13 2012
On Mon, Feb 13, 2012 at 6:47 PM, Sean Kelly <sean invisibleduck.org> wrote:On Feb 13, 2012, at 12:44 PM, jdrewsen wrote:I agree. Let me know how I can improve this...A first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging.I think that's what vlog is for, it just isn't particularly well documented.
Feb 13 2012
On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen <jdrewsen nospam.com> wrote:A first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What let you do?/Jonas
Feb 13 2012
On 2/13/12 8:28 PM, Jose Armando Garcia wrote:On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen<jdrewsen nospam.com> wrote:Let's not forget we could always do debug log(stuff); AndreiA first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What let you do?
Feb 13 2012
On Tuesday, 14 February 2012 at 02:28:11 UTC, Jose Armando Garcia wrote:On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen <jdrewsen nospam.com> wrote:As Sean mentioned the vlog function may be the one I want. Maybe it is okey not to have a debug severity but then a default on the vlog level parameter would be nice. That would make quick debug prints a tad simpler vlog("This is a dbg message"); I know this is a small thing... but to prevent death by a 1000 cuts. /JonasA first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What doesn't let you do?
Feb 14 2012
On Tue, Feb 14, 2012 at 8:42 AM, jdrewsen <jdrewsen nospam.com> wrote:On Tuesday, 14 February 2012 at 02:28:11 UTC, Jose Armando Garcia wrote:If we do set a default what should it be? It is not clear to me what value we should pick so if you have any suggestions let me know.On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen <jdrewsen nospam.com> wrote:As Sean mentioned the vlog function may be the one I want. Maybe it is okey not to have a debug severity but then a default on the vlog level parameter would be nice. That would make quick debug prints a tad simplerA first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What let you do?vlog("This is a dbg message"); I know this is a small thing... but to prevent death by a 1000 cuts. /Jonas
Feb 14 2012
On Tuesday, 14 February 2012 at 16:21:42 UTC, Jose Armando Garcia wrote:On Tue, Feb 14, 2012 at 8:42 AM, jdrewsen <jdrewsen nospam.com> wrote:IMO a default severity level is not a good idea, not explicit to begin with. As i suggested on another reply, getting rid of the instantiations solve it. We lose nothing and gain a common keyword. I used to have severity levels for my logging library in c++. As soon as i got the C++0x options i thrashed them all. Now instead of: txt(error) << "this is: " << it; i just got: error("this is: ", it); Win win for every aspect of it. And got rid of the keyword "txt".On Tuesday, 14 February 2012 at 02:28:11 UTC, Jose Armando Garcia wrote:If we do set a default what should it be? It is not clear to me what value we should pick so if you have any suggestions let me know.On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen <jdrewsen nospam.com> wrote:As Sean mentioned the vlog function may be the one I want. Maybe it is okey not to have a debug severity but then a default on the vlog level parameter would be nice. That would make quick debug prints a tad simplerA first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What doesn't let you do?
Feb 14 2012
On Tuesday, 14 February 2012 at 17:48:06 UTC, so wrote:On Tuesday, 14 February 2012 at 16:21:42 UTC, Jose Armando Garcia wrote:I also like your proposal better. In the end I just want a simple to type function call syntax or it will be tempting to fallback to writeln(...). /JonasOn Tue, Feb 14, 2012 at 8:42 AM, jdrewsen <jdrewsen nospam.com> wrote:IMO a default severity level is not a good idea, not explicit to begin with. As i suggested on another reply, getting rid of the instantiations solve it. We lose nothing and gain a common keyword. I used to have severity levels for my logging library in c++. As soon as i got the C++0x options i thrashed them all. Now instead of: txt(error) << "this is: " << it; i just got: error("this is: ", it); Win win for every aspect of it. And got rid of the keyword "txt".On Tuesday, 14 February 2012 at 02:28:11 UTC, Jose Armando Garcia wrote:If we do set a default what should it be? It is not clear to me what value we should pick so if you have any suggestions let me know.On Mon, Feb 13, 2012 at 6:44 PM, jdrewsen <jdrewsen nospam.com> wrote:As Sean mentioned the vlog function may be the one I want. Maybe it is okey not to have a debug severity but then a default on the vlog level parameter would be nice. That would make quick debug prints a tad simplerA first quick observation: I vote for a debug severity level. Then make that default to the template parameter for log: template log(Severity severity = Severity.debug) That would make it nice for good old print debugging. log("This is a dbg message");I like the idea of having a default. Not sure about adding debug. What doesn't let you do?
Feb 14 2012
Log levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the only overhead would be searching once through the format string in the case of format placeholders. A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nicely formatted HTML file with built-in JavaScript to be able to filter messages by priority or module. Maybe this is too much for a standard library implementation though. Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application). Of course, one can also simply write a "MultiDispatchLogger"... A format option to log the thread name instead of just the ID.
Feb 13 2012
On 14 February 2012 10:17, S=C3=B6nke Ludwig <ludwig informatik.uni-luebeck.de> wrote:Log levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the on=lyoverhead would be searching once through the format string in the case of format placeholders. A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nicel=yformatted HTML file with built-in JavaScript to be able to filter message=sby priority or module. Maybe this is too much for a standard library implementation though. Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application).=Ofcourse, one can also simply write a "MultiDispatchLogger"... A format option to log the thread name instead of just the ID.I agree that there needs to be an easy to use format-based logger, even if its just logf template that calls format on the filter, since writing `log!(info).format("my string %s", s);` looks bad compared to `logf!info("my string %s", s);` Looking through the docs, there needs to be a better indication of configuration in the primary example, since you don't even mention it, I thought it might not exist. A built-in console logger should probably be available, one that writes to stdout at the very least, since I often need log messages for debugging, other loggers can be build on top of the Logger interface, separate from the library, but I imagine that many people would want a console logger and doing it in the standard library will prevent too much repeated work. It would also be an idea to make it the default, but at this point I can't really separate out my practices from what I think most people do. A debug-level log would be nice, but I don't really care either way. A built-in MultiDispatchLogger (or similar) would be nice, but I don't think it really matters. Otherwise, I think it all looks good; fairly simple to use and configure, ability to override the defaults if needed, ability to swap out backends at runtime. The docs need work, but docs always need work :P. It might not mean much, but this gets my approval. James Miller
Feb 13 2012
On Mon, Feb 13, 2012 at 7:17 PM, S=F6nke Ludwig <ludwig informatik.uni-luebeck.de> wrote:Log levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the on=lyoverhead would be searching once through the format string in the case of format placeholders.No, no reason. I guess making the opCall an alias to format is better. That means the concatenate call will be: log!info.write(...) Not that great looking. Suggestions?A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications.Never used OutputDebugString. Do you mind sending a patch if std.log gets commit to phobos? Thanks.One kind of log writer that I have in my code is one that outputs a nicel=yformatted HTML file with built-in JavaScript to be able to filter message=sby priority or module. Maybe this is too much for a standard library implementation though.What I would really like is to eventually write a backend logger that sends the message to elasticsearch. That would make this usable in a data center environment. For that I first need to extend the LogMessage class.Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application).=Ofcourse, one can also simply write a "MultiDispatchLogger"...FileLogger can write to a set of files and/or stderr.A format option to log the thread name instead of just the ID.Good idea.
Feb 13 2012
On Mon, Feb 13, 2012 at 9:12 PM, James Miller <james aatch.net> wrote:On 14 February 2012 10:17, S=F6nke Ludwig <ludwig informatik.uni-luebeck.de> wrote:tLog levels "debug" and maybe also "trace" would be useful, but I see tha=nlyvlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the o=foverhead would be searching once through the format string in the case o=rformat placeholders. A predefined logger for OutputDebugString on Windows would be useful - o=lymaybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nice=esformatted HTML file with built-in JavaScript to be able to filter messag=. Ofby priority or module. Maybe this is too much for a standard library implementation though. Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application)=At the top of the documentation I wanted information on how to use the module for the common developer. To me the common developer is going to write log message not configure the log module/framework. The user that is going to configure the library can read the whole document or the Configuration classes. Thoughts?course, one can also simply write a "MultiDispatchLogger"... A format option to log the thread name instead of just the ID.I agree that there needs to be an easy to use format-based logger, even if its just logf template that calls format on the filter, since writing `log!(info).format("my string %s", s);` looks bad compared to `logf!info("my string %s", s);` Looking through the docs, there needs to be a better indication of configuration in the primary example, since you don't even mention it, I thought it might not exist.A built-in console logger should probably be available, one that writes to stdout at the very least, since I often need log messages for debugging, other loggers can be build on top of the Logger interface, separate from the library, but I imagine that many people would want a console logger and doing it in the standard library will prevent too much repeated work. It would also be an idea to make it the default, but at this point I can't really separate out my practices from what I think most people do.The default FileLogger can do this. See --logtostderr, --alsologtostderr and --stderrthreshold.A debug-level log would be nice, but I don't really care either way. A built-in MultiDispatchLogger (or similar) would be nice, but I don't think it really matters.Yeah. We could use a few other loggers. But we should think of this as a living module. The most important thing I think is that we can make this future improvements without breaking existing users.Otherwise, I think it all looks good; fairly simple to use and configure, ability to override the defaults if needed, ability to swap out backends at runtime. The docs need work, but docs always need work :P. It might not mean much, but this gets my approval. James Miller
Feb 13 2012
On 2012-02-13 22:17, Sönke Ludwig wrote:Log levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the only overhead would be searching once through the format string in the case of format placeholders. A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nicely formatted HTML file with built-in JavaScript to be able to filter messages by priority or module. Maybe this is too much for a standard library implementation though.It would be nice to be able to plug in different formatters.Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application). Of course, one can also simply write a "MultiDispatchLogger"... A format option to log the thread name instead of just the ID.-- /Jacob Carlborg
Feb 13 2012
On Tue, Feb 14, 2012 at 5:44 AM, Jacob Carlborg <doob me.com> wrote:On 2012-02-13 22:17, S=F6nke Ludwig wrote:What do you mean by formatter? For example the default Logger (FileLogger) allow you to specify the format line see FileLogger.Configuration.lineFormat If you want to do the HTML stuff S=F6nke mentioned then you need to inherit Logger and overwrite config.logger. Mind you that the Logger API should be view almost like a journaling API and HTML is a document so the differences need to be reconciled in the implementation of Logger. Thanks, -JoseLog levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the only overhead would be searching once through the format string in the case of format placeholders. A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nicely formatted HTML file with built-in JavaScript to be able to filter messages by priority or module. Maybe this is too much for a standard library implementation though.It would be nice to be able to plug in different formatters.Support for multiple log writers can be useful (e.g. logging to a file + logging to stdout or to a log control inside of the running application). Of course, one can also simply write a "MultiDispatchLogger"... A format option to log the thread name instead of just the ID.-- /Jacob Carlborg
Feb 14 2012
On 2012-02-14 17:19, Jose Armando Garcia wrote:On Tue, Feb 14, 2012 at 5:44 AM, Jacob Carlborg<doob me.com> wrote:Yeah, I was referring to something like outputting HTML. Ok, I see. -- /Jacob CarlborgOn 2012-02-13 22:17, Sönke Ludwig wrote:What do you mean by formatter? For example the default Logger (FileLogger) allow you to specify the format line see FileLogger.Configuration.lineFormat If you want to do the HTML stuff Sönke mentioned then you need to inherit Logger and overwrite config.logger. Mind you that the Logger API should be view almost like a journaling API and HTML is a document so the differences need to be reconciled in the implementation of Logger.Log levels "debug" and maybe also "trace" would be useful, but I see that vlog(n)() is meant for that purpose. I would just prefer explicit names instead of just numbers. Is there a compelling reason why formatted logging is not the default? I find that most logging calls in practice use formatted output, and the only overhead would be searching once through the format string in the case of format placeholders. A predefined logger for OutputDebugString on Windows would be useful - or maybe it could be used instead of stdout at least for non-console applications. One kind of log writer that I have in my code is one that outputs a nicely formatted HTML file with built-in JavaScript to be able to filter messages by priority or module. Maybe this is too much for a standard library implementation though.It would be nice to be able to plug in different formatters.
Feb 14 2012
On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidGood work. One suggestion. Instantiating a template for each log rather verbose for such common thing. I suggest: (Just to demonstrate) alias global_logger!sev_info info; alias global_logger!sev_warning warning; alias global_logger!sev_error error; alias global_logger!sev_critical critical; alias global_logger!sev_dfatal dfatal; alias global_logger!sev_fatal fatal; As we are pulling severity levels to global namespace anyway, this will save us some verbosity and the keyword "log".
Feb 13 2012
On Mon, Feb 13, 2012 at 9:37 PM, so <so so.so> wrote:On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:I like it! I think I tried this before but I thought "compiled time" instantiation of the templates was not working properly with alias. Let me try it again and report back...There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidGood work. One suggestion. Instantiating a template for each log rather verbose for such common thing. I suggest: (Just to demonstrate) alias global_logger!sev_info info; alias global_logger!sev_warning warning; alias global_logger!sev_error error; alias global_logger!sev_critical critical; alias global_logger!sev_dfatal dfatal; alias global_logger!sev_fatal fatal; As we are pulling severity levels to global namespace anyway, this will save us some verbosity and the keyword "log".
Feb 13 2012
On 2012-02-14 00:37, so wrote:On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:It would then be possible to use renamed imports to have something like this: import log = std.log; log.info("foo"); Which looks quite nice I think. -- /Jacob CarlborgThere are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidGood work. One suggestion. Instantiating a template for each log rather verbose for such common thing. I suggest: (Just to demonstrate) alias global_logger!sev_info info; alias global_logger!sev_warning warning; alias global_logger!sev_error error; alias global_logger!sev_critical critical; alias global_logger!sev_dfatal dfatal; alias global_logger!sev_fatal fatal; As we are pulling severity levels to global namespace anyway, this will save us some verbosity and the keyword "log".
Feb 13 2012
On Monday, February 13, 2012 23:58:38 Jose Armando Garcia wrote:On Mon, Feb 13, 2012 at 4:19 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:Personally, I'd just copy what syslog does in terms of log levels. Then std.log can use syslog and everything maps wonderfully. - Jonathan M DavisOn Monday, February 13, 2012 17:49:49 David Nadlinger wrote:I am trying to minimize the number of predefined log levels. One of the big problems I see with having too many log levels is that the programmer never knows which one to use. I think std.log makes this very clear: 1. Log at fatal if you want the application to assert 2. Log at critical if you want the thread to throw 3. Log at error if you detect a programming bug (invariant violation) but you wish to continue and cross your finger 4. Log at warning if you detected peculiar condition yet the program was coded to handle it. 5. Log at info if you want to document an action/state. 6. verbose log for trace/debugging specific parts of a program. I think it would help me that instead of suggesting another level we instead state what we think the user would like to do or log but the framework as defined doesn't let the user do.You define the Severity enum members starting with fatal as 0. Why not the other way round – so that severityA < severityB would do what you (or at least I) would expect?syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) as the weakest. The greater the number, the more logging output, you're going to see. So, he's following syslog in that respect, though he doesn't have as many log levels. He should probably add at least debug. He also aliases them to module-level symbols for some reason, which is a big no-no IMHO.
Feb 13 2012
On Tue, Feb 14, 2012 at 12:02 AM, Jonathan M Davis <jmdavisProg gmx.com> wr= ote:On Monday, February 13, 2012 23:58:38 Jose Armando Garcia wrote:tOn Mon, Feb 13, 2012 at 4:19 PM, Jonathan M Davis <jmdavisProg gmx.com>wrote:On Monday, February 13, 2012 17:49:49 David Nadlinger wrote:You define the Severity enum members starting with fatal as 0. Why no=outhe other way round =96 so that severityA < severityB would do what y=o(or at least I) would expect?syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) as the weakest. The greater the number, the more logging output, you're going to see. So, he's following syslog in that respect, though he doesn't have as many log levels. He should probably add at least debug. He als=Do you think that our users will really want to send "debug" message to syslog? Either way I don't think that is a reason to add debug level. If we used the common denominator to determine the set of features that set would be quite large. The implementation of the Logger interface can do its best to map the severity from std.log to something syslog likes. This is exactly what SLF4J does with Log4J, java.util.logger, syslog, etc.Personally, I'd just copy what syslog does in terms of log levels. Then std.log can use syslog and everything maps wonderfully.aliases them to module-level symbols for some reason, which is a big no-no IMHO.I am trying to minimize the number of predefined log levels. One of the big problems I see with having too many log levels is that the programmer never knows which one to use. I think std.log makes this very clear: 1. Log at fatal if you want the application to assert 2. Log at critical if you want the thread to throw 3. Log at error if you detect a programming bug (invariant violation) but you wish to continue and cross your finger 4. Log at warning if you detected peculiar condition yet the program was coded to handle it. 5. Log at info if you want to document an action/state. 6. verbose log for trace/debugging specific parts of a program. I think it would help me that instead of suggesting another level we instead state what we think the user would like to do or log but the framework as defined doesn't let the user do.- Jonathan M Davis
Feb 13 2012
On Tuesday, February 14, 2012 01:16:29 Jose Armando Garcia wrote:On Tue, Feb 14, 2012 at 12:02 AM, Jonathan M Davis <jmdavisProg gmx.c=om>=20 wrote:.com>On Monday, February 13, 2012 23:58:38 Jose Armando Garcia wrote:On Mon, Feb 13, 2012 at 4:19 PM, Jonathan M Davis <jmdavisProg gmx=Why not=20 wrote:On Monday, February 13, 2012 17:49:49 David Nadlinger wrote:You define the Severity enum members starting with fatal as 0. =ld do what youthe other way round =E2=80=93 so that severityA < severityB wou=as the(or at least I) would expect?=20 syslog defines 0 (LOG_EMERG) as the strongest and 7 (LOG_DEBUG) =goingweakest. The greater the number, the more logging output, you're=sn'tto see. So, he's following syslog in that respect, though he doe=He alsohave as many log levels. He should probably add at least debug. =bigaliases them to module-level symbols for some reason, which is a=fno-no IMHO.=20 I am trying to minimize the number of predefined log levels. One o=the big problems I see with having too many log levels is that the=sprogrammer never knows which one to use. I think std.log makes thi=on)very clear: =20 1. Log at fatal if you want the application to assert 2. Log at critical if you want the thread to throw 3. Log at error if you detect a programming bug (invariant violati=ambut you wish to continue and cross your finger 4. Log at warning if you detected peculiar condition yet the progr=wewas coded to handle it. 5. Log at info if you want to document an action/state. 6. verbose log for trace/debugging specific parts of a program. =20 I think it would help me that instead of suggesting another level =heinstead state what we think the user would like to do or log but t=Thenframework as defined doesn't let the user do.=20 Personally, I'd just copy what syslog does in terms of log levels. =etc. Where I work, we log debug messages to syslog all the time when the pro= duct is=20 under development. It's incredibly useful. And on Linux, syslog is _the= _=20 logging facility. It's where all log messages should go. Then syslog ca= n be=20 configured to split up log files per program or log level or whatever e= lse you=20 want to do on that particular system. But regardless, all logging goes = to=20 syslog. That's what it's for. - Jonathan M Davisstd.log can use syslog and everything maps wonderfully.=20 Do you think that our users will really want to send "debug" message to syslog? Either way I don't think that is a reason to add debug level. If we used the common denominator to determine the set of features that set would be quite large. The implementation of the Logger interface can do its best to map the severity from std.log to something syslog likes. =20 This is exactly what SLF4J does with Log4J, java.util.logger, syslog,=
Feb 13 2012
Am Mon, 13 Feb 2012 19:22:54 -0800 schrieb Jonathan M Davis <jmdavisProg gmx.com>:Where I work, we log debug messages to syslog all the time when the product is under development. It's incredibly useful. And on Linux, syslog is _the_ logging facility.Right now. But once systemd took over the world: https://docs.google.com/document/pub?id=1IC9yOXj7j6cdLLxWEBAGRL6wl97tFxgjLUEHIX3MSTs&pli=1
Feb 14 2012
On 2/13/12 9:50 AM, David Nadlinger wrote:Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Thanks Jose and David. I made a pass, here are a few thoughts: * "different verbose level" -> "different verbosity levels" * "functionality to disabled and enabled" -> "functionality to disable and enable" * "enviroment variables, and their meaning see" -> "enviroment variables and their meaning, see" * In code example: "Every nine" -> "Write every 9 passes" * In code example: unbraced try statement is odd. We should use our own conventions in examples. * In code example: plant an assert(false, "Never reached") after log!fatal. * first() and every() are quite useful. I'm thinking of complementing them with after(). "Once" is first(1). * "Descripton of the supported severities." -> "Description of supported severities." (notice the typo too) * vlog should take uint, not int. * When passing multiple parameters to log, they must be stringized automatically. So log!error("Log an ", to!string(Severity.error), " message!"); becomes log!error("Log an ", Severity.error, " message!"); * The examples right inside LogFilter don't mention it at all. I assume log!xyz has type LogFilter or something. That must be stated in writing. * log!info.when(first())("Only log this the first time in the loop") should really be log!info.when(first())("Only log this one time per application run"). * No examples include durations. * There might be a better name for Rich. * assert(value == true); => assert(value); Andrei
Feb 13 2012
On Tue, Feb 14, 2012 at 4:50 AM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 2/13/12 9:50 AM, David Nadlinger wrote:Fixed all of the above comments.Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Thanks Jose and David. I made a pass, here are a few thoughts: * "different verbose level" -> "different verbosity levels" * "functionality to disabled and enabled" -> "functionality to disable and enable" * "enviroment variables, and their meaning see" -> "enviroment variables and their meaning, see" * In code example: "Every nine" -> "Write every 9 passes" * In code example: unbraced try statement is odd. We should use our own conventions in examples. * In code example: plant an assert(false, "Never reached") after log!fatal.* first() and every() are quite useful. I'm thinking of complementing them with after(). "Once" is first(1).We do have after(). It should be the second to last document block in std_log.html. Yep, "Once is first(1) or just first() as the default value for first is 1. The rest (every and after) don't have default values because I couldn't find one that made sense to me.* "Descripton of the supported severities." -> "Description of supported severities." (notice the typo too)Fixed.* vlog should take uint, not int.There is a subtle reason why I decided to use int and not unit. I suspect that most user will use non-negative values when using vlog. They will probably start by using either vlog(0) and/or vlog(1). To enable vlog(0) and vlog(1) they need to config.maxVerboseLevel(1), config.maxVerboseLevel(2), etc. To enable vlog(0) and disable vlog(1) they need to config.maxVerboseLevel(0). What if they want to disable vlog(0)? They can't if we use uint. By using int instead of uint they can always specify -1. Now, you can say that you can apply the same logic to int.min. They will never be able to disable vlog(int.min). My argument is that most user will not log using vlog(int.min) and the ones that do are very familiar with the implementation and are aware of the consequences. Thoughts?* When passing multiple parameters to log, they must be stringized automatically. So log!error("Log an ", to!string(Severity.error), " message!"); becomes log!error("Log an ", Severity.error, " message!");Fixed.* The examples right inside LogFilter don't mention it at all. I assume log!xyz has type LogFilter or something. That must be stated in writing.Yes, but technically "template log" can either alias to LogFilter or NoopLogFilter (used for compiled time disabling). But yes they have structurally the same set of public methods. Fixed.* log!info.when(first())("Only log this the first time in the loop") should really be log!info.when(first())("Only log this one time per application run").It is actually per thread run. Change it to: info.when(first())("Only log this one time per thread run")* No examples include durations.Not sure it if help but a copied the unittest for duration. I should be readable.* There might be a better name for Rich.Suggestions?* assert(value == true); => assert(value);Fixed. Thanks! -JoseAndrei
Feb 14 2012
On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidUpdated wiki: http://prowiki.org/wiki4d/wiki.cgi?ReviewQueue /Jonas
Feb 14 2012
On 2012-02-13 16:50, David Nadlinger wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidIs it possible to log to other locations, i.e. to the standard location for the given platform. -- /Jacob Carlborg
Feb 14 2012
On 2/14/12 2:14 PM, Jacob Carlborg wrote:Is it possible to log to other locations, i.e. to the standard location for the given platform.While the current proposal only includes a file backend, my understanding is that this could easily be added by providing an appropriate implementation of the Logger interface. Generally useful implementations (e.g. syslog, …) would probably be a good candidate for inclusion into Phobos. David
Feb 14 2012
On 2012-02-14 14:24, David Nadlinger wrote:On 2/14/12 2:14 PM, Jacob Carlborg wrote:Ok, I see. I don't think it would be necessary with different backends, as long as there's an interface available, at least not at the first stage. -- /Jacob CarlborgIs it possible to log to other locations, i.e. to the standard location for the given platform.While the current proposal only includes a file backend, my understanding is that this could easily be added by providing an appropriate implementation of the Logger interface. Generally useful implementations (e.g. syslog, …) would probably be a good candidate for inclusion into Phobos. David
Feb 14 2012
On Tue, Feb 14, 2012 at 11:14 AM, Jacob Carlborg <doob me.com> wrote:On 2012-02-13 16:50, David Nadlinger wrote:What do you mean by location? If you mean file system directory then: property string logDirectory(string logDirectory); const const property string logDirectory(); Specifies the directory where log files are created. The default value for this property is the value in the environment variable LOGDIR. If LOGDIR is not set, then TEST_TMPDIR is used. If TEST_TMPDIR is not set, then it logs to the current directory. If you mean file name, you have 'fileNamePrefixes' and 'fileNameExtension'. If you mean syslog then for now the user needs to implement this but I foresee us implementing this in phobos in the near future. Thanks, -JoseThere are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidIs it possible to log to other locations, i.e. to the standard location for the given platform.-- /Jacob Carlborg
Feb 14 2012
On 2012-02-14 17:27, Jose Armando Garcia wrote:On Tue, Feb 14, 2012 at 11:14 AM, Jacob Carlborg<doob me.com> wrote:I meant something like a general interface one could implement to be able to log to basically anywhere, not only files. Say that I would want to output the log in a window in a GUI application, for example. -- /Jacob CarlborgOn 2012-02-13 16:50, David Nadlinger wrote:What do you mean by location? If you mean file system directory then: property string logDirectory(string logDirectory); const const property string logDirectory(); Specifies the directory where log files are created. The default value for this property is the value in the environment variable LOGDIR. If LOGDIR is not set, then TEST_TMPDIR is used. If TEST_TMPDIR is not set, then it logs to the current directory. If you mean file name, you have 'fileNamePrefixes' and 'fileNameExtension'. If you mean syslog then for now the user needs to implement this but I foresee us implementing this in phobos in the near future.There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidIs it possible to log to other locations, i.e. to the standard location for the given platform.
Feb 14 2012
On Mon, Feb 13, 2012 at 1:50 PM, David Nadlinger <see klickverbot.at> wrote= :There are several modules in the review queue right now, and to get thing=sgoing, I have volunteered to manage the review of Jose's std.log proposal=.Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd=3cc8e6f5Docs: http://jsancio.github.com/phobos/phobos/std_log.htmlUpdated the document an implementation to reflect every suggest for I replied to with the exception of providing a format parameter for thread name. Should have that ready later today. Let me know if I missed anything. API changes: 1. Dropped log!info("message"), etc. Use info("message), etc. 2. opCall now alias to format. Ie. info("Format %s message", Severity.info)= . this means that to concatenate strings you need to info.write("Hello ", "world");Known remaining issues: =A0- Proof-reading of the docs is required. =A0- Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the =NGand ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'=dwarmly encourage everyone to actively try out the module or compare it wi=thany logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! David
Feb 14 2012
On Tuesday, 14 February 2012 at 16:12:57 UTC, Jose Armando Garcia wrote:On Mon, Feb 13, 2012 at 1:50 PM, David Nadlinger <see klickverbot.at> wrote:In the introduction text the references to Configuration etc. should be made into links. /JonasThere are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std log.htmlUpdated the document an implementation to reflect every suggest for I replied to with the exception of providing a format parameter for thread name. Should have that ready later today. Let me know if I missed anything. API changes: 1. Dropped log!info("message"), etc. Use info("message), etc. 2. opCall now alias to format. Ie. info("Format %s message", Severity.info). this means that to concatenate strings you need to info.write("Hello ", "world");
Feb 14 2012
On Tue, Feb 14, 2012 at 4:44 PM, jdrewsen <jdrewsen nospam.com> wrote:On Tuesday, 14 February 2012 at 16:12:57 UTC, Jose Armando Garcia wrote:bd3cc8e6f5On Mon, Feb 13, 2012 at 1:50 PM, David Nadlinger <see klickverbot.at> wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293c=adeIn the introduction text the references to Configuration etc. should be m=Docs: http://jsancio.github.com/phobos/phobos/std log.htmlUpdated the document an implementation to reflect every suggest for I replied to with the exception of providing a format parameter for thread name. Should have that ready later today. Let me know if I missed anything. API changes: 1. Dropped log!info("message"), etc. Use info("message), etc. 2. opCall now alias to format. Ie. info("Format %s message", Severity.info). =A0this means that to concatenate strings you need to info.write("Hello ", "world");into links.I would love to do that. How do you do that with ddoc?/Jonas
Feb 14 2012
On Tuesday, 14 February 2012 at 18:51:20 UTC, Jose Armando Garcia wrote:On Tue, Feb 14, 2012 at 4:44 PM, jdrewsen <jdrewsen nospam.com> wrote:For example: $(LREF Configuration) The LREF macro is defined in https://github.com/D-Programming-Language/d-programming-language.org/blob/ aster/std.ddoc#L293 along with other useful macros. /JonasOn Tuesday, 14 February 2012 at 16:12:57 UTC, Jose Armando Garcia wrote:I would love to do that. How do you do that with ddoc?On Mon, Feb 13, 2012 at 1:50 PM, David Nadlinger <see klickverbot.at> wrote:In the introduction text the references to Configuration etc. should be made into links.There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std log.htmlUpdated the document an implementation to reflect every suggest for I replied to with the exception of providing a format parameter for thread name. Should have that ready later today. Let me know if I missed anything. API changes: 1. Dropped log!info("message"), etc. Use info("message), etc. 2. opCall now alias to format. Ie. info("Format %s message", Severity.info). Â this means that to concatenate strings you need to info.write("Hello ", "world");
Feb 14 2012
On Mon, Feb 13, 2012 at 1:50 PM, David Nadlinger <see klickverbot.at> wrote= :There are several modules in the review queue right now, and to get thing=sgoing, I have volunteered to manage the review of Jose's std.log proposal=.Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd=3cc8e6f5 It is better if we use this: https://github.com/D-Programming-Language/phobos/pull/432/files That link will stay up to date as I make changes to the code.Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: =A0- Proof-reading of the docs is required. =A0- Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the =NGand ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'=dwarmly encourage everyone to actively try out the module or compare it wi=thany logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! David
Feb 14 2012
On 02/13/2012 07:50 AM, David Nadlinger wrote:Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058)This is somehow bad. Review a piece of library-software by using a beta compiler and beta-library.
Feb 12 2012
On Tuesday, 14 February 2012 at 21:47:42 UTC, bls wrote:This is somehow bad. Review a piece of library-software by using a beta compiler and beta-library.Indeed, never happened such thing in whole compiler/language development history.
Feb 15 2012
On Tuesday, 14 February 2012 at 21:47:42 UTC, bls wrote:This is somehow bad. Review a piece of library-software by using a beta compiler and beta-library.I don't quite see where the problem is with that. Besides, 2.058 is already out now (and was scheduled to be released on Feb 13). David
Feb 15 2012
On Monday, February 13, 2012 16:50:04 David Nadlinger wrote:Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Why does vlog even exist? It's a needless complication IMHO. Let the log levels manage what does and doesn't get logged. I see no reason to add the concept of verbosity on top of that. It's a needless complication. Also, _please_ add a debug level. Personally, I'd argue for simply copying syslog's levels and matching them, since ideally any logging on Linux would be going to syslog anyway. But there are good reasons to have messages beyond info. I sure wouldn't want _all_ messages which don't indicate a problem in the app to be marked as info. For instance, what if I want to have info displayed in release mode but want greater verbosity in debug mode? I'd need another log level which isn't there. Using the concept of verbosity to try and handle this is a needless complication. syslog has #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ And I'd like to at least see notice and debug added. While we're at it, what's the point of dfatal? Why on earth would a _fatal_ condition not be fatal if it were in release mode if it were fatal in debug mode? Is it fatal or not? It seems to me like another needless complication. If you're going to have write, then have writef, not format. Then it's actually consistent with our normal I/O functions. Also, do writef and format automatically append a newline? If so, then they should be writeln and writefln. Rich is a horrible name IMHO. It says nothing about what it actually is or does. I'm not sure what a good name would be (BoolMessage?, LogResult?), but Rich by itself is very confusing and utterly uninformative. And why does Configuration's logger property throw if you set it after a logging call has been made. Is it really that inconceivable that someone would swap out loggers at runtime? Or is the idea that you'd swap out the Configuration? - Jonathan M Davis
Feb 16 2012
Am 16.02.2012 10:21, schrieb Jonathan M Davis:On Monday, February 13, 2012 16:50:04 David Nadlinger wrote:Well in addition to Debug I would also like to see Trace but it's f. ex. hard for me to tell the difference between Info and Notice and their names do not imply that certain severity order IMO. So I see a point in the argument that vlog() allows everyone to be happy without endless numbers of predefined log levels.. however I'm also not quite convinced.Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Why does vlog even exist? It's a needless complication IMHO. Let the log levels manage what does and doesn't get logged. I see no reason to add the concept of verbosity on top of that. It's a needless complication. Also, _please_ add a debug level. Personally, I'd argue for simply copying syslog's levels and matching them, since ideally any logging on Linux would be going to syslog anyway. But there are good reasons to have messages beyond info. I sure wouldn't want _all_ messages which don't indicate a problem in the app to be marked as info. For instance, what if I want to have info displayed in release mode but want greater verbosity in debug mode? I'd need another log level which isn't there. Using the concept of verbosity to try and handle this is a needless complication. syslog has #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ And I'd like to at least see notice and debug added.While we're at it, what's the point of dfatal? Why on earth would a _fatal_ condition not be fatal if it were in release mode if it were fatal in debug mode? Is it fatal or not? It seems to me like another needless complication. If you're going to have write, then have writef, not format. Then it's actually consistent with our normal I/O functions. Also, do writef and format automatically append a newline? If so, then they should be writeln and writefln.I think the names should be as short as possible for the common 99% case. As this is not a general purpose stream, I think it is fine to drop the 'ln'. And the current version that defines info("") as the version that can format and info.write("") as the plain string version seems to be quite optimal in this regard. In my optinion, more descriptive names would just impair readability here instead of helping. They will be written endless number of times but do not influence the program flow and should immediately understandable by anyone who sees them. But something like log.warn/logf.warn or log.warn/log.warnf might also work if you really want the consistency...Rich is a horrible name IMHO. It says nothing about what it actually is or does. I'm not sure what a good name would be (BoolMessage?, LogResult?), but Rich by itself is very confusing and utterly uninformative. And why does Configuration's logger property throw if you set it after a logging call has been made. Is it really that inconceivable that someone would swap out loggers at runtime? Or is the idea that you'd swap out the Configuration? - Jonathan M Davis
Feb 16 2012
On 2012-02-16 10:57, Sönke Ludwig wrote:Am 16.02.2012 10:21, schrieb Jonathan M Davis:I think this is way too many levels. Why not just define few levels (around three) and let the user define new levels when needed. -- /Jacob CarlborgOn Monday, February 13, 2012 16:50:04 David Nadlinger wrote:Well in addition to Debug I would also like to see Trace but it's f. ex. hard for me to tell the difference between Info and Notice and their names do not imply that certain severity order IMO. So I see a point in the argument that vlog() allows everyone to be happy without endless numbers of predefined log levels.. however I'm also not quite convinced.Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Why does vlog even exist? It's a needless complication IMHO. Let the log levels manage what does and doesn't get logged. I see no reason to add the concept of verbosity on top of that. It's a needless complication. Also, _please_ add a debug level. Personally, I'd argue for simply copying syslog's levels and matching them, since ideally any logging on Linux would be going to syslog anyway. But there are good reasons to have messages beyond info. I sure wouldn't want _all_ messages which don't indicate a problem in the app to be marked as info. For instance, what if I want to have info displayed in release mode but want greater verbosity in debug mode? I'd need another log level which isn't there. Using the concept of verbosity to try and handle this is a needless complication. syslog has #define LOG_EMERG 0 /* system is unusable */ #define LOG_ALERT 1 /* action must be taken immediately */ #define LOG_CRIT 2 /* critical conditions */ #define LOG_ERR 3 /* error conditions */ #define LOG_WARNING 4 /* warning conditions */ #define LOG_NOTICE 5 /* normal but significant condition */ #define LOG_INFO 6 /* informational */ #define LOG_DEBUG 7 /* debug-level messages */ And I'd like to at least see notice and debug added.
Feb 16 2012
I think this is way too many levels. Why not just define few levels (around three) and let the user define new levels when needed.I agree this is too many level, though I think letting the user define their own levels is a needless complication.From experience, I would recommend:- CRIT - the application cannot continue - ERROR - the application cannot carry out the requested task - WARN - the requested task cannot be completed normally, but we can work around it - INFO - FYI. Things sysadmins would like to know. - DEBUG - For developers debugging. - TRACE (maybe) - also sometimes called fine or verbose - for developers debugging. If an application needs separate channels of logging, I would using a separate logger instance for different logging categories.
Feb 16 2012
Am 17.02.2012 02:49, schrieb Jonathan Stephens:Thats also exactly my experience (and what I use).I think this is way too many levels. Why not just define few levels (around three) and let the user define new levels when needed.I agree this is too many level, though I think letting the user define their own levels is a needless complication.From experience, I would recommend:- CRIT - the application cannot continue - ERROR - the application cannot carry out the requested task - WARN - the requested task cannot be completed normally, but we can work around it - INFO - FYI. Things sysadmins would like to know. - DEBUG - For developers debugging. - TRACE (maybe) - also sometimes called fine or verbose - for developers debugging.
Feb 17 2012
On Thu, Feb 16, 2012 at 06:49:41PM -0700, Jonathan Stephens wrote:[...]I think this is way too many levels. Why not just define few levels (around three) and let the user define new levels when needed.I agree this is too many level, though I think letting the user define their own levels is a needless complication.From experience, I would recommend:- CRIT - the application cannot continue - ERROR - the application cannot carry out the requested task - WARN - the requested task cannot be completed normally, but we can work around it - INFO - FYI. Things sysadmins would like to know. - DEBUG - For developers debugging. - TRACE (maybe) - also sometimes called fine or verbose - for developers debugging.From my experience, such a proliferation of log levels is rarely usedcorrectly. Most people, sadly to say, can't be bothered to read the definitions of what each level is supposed to be, and will just copy-n-paste the first instance they find. Of course, copying CRIT or ERROR will quickly get a high-priority bug filed against it, but besides CRIT and ERROR, the rest of the levels are rarely used properly. I've seen people use WARN just because they think it's appropriate for "warning" the developer that a certain condition has happened that might trigger the bug they're hunting for. Then afterwards they forget to turn that off, and the log fills up with irrelevant messages. Similarly, INFO tends to be interpreted as "garbage dump for anything I might want to know while writing this code, who cares what happens to those messages afterwards". DEBUG and TRACE are rarely ever used after 4 or 5 developers have had their hands on it, because turning those on will usually flood the logs with reams and reams of irrelevant messages from unrelated modules, so most people would stop using it after the first time. Bottomline: reduce the number of channels, and let the programmer define their own channels if they need to. Module-specific channels are the best, so that you don't get reams of messages from completely unrelated code. But only the user knows what modules they have, so let them make that decision. T -- Those who don't understand Unix are condemned to reinvent it, poorly.
Feb 16 2012
On Friday, 17 February 2012 at 06:39:29 UTC, H. S. Teoh wrote:[…] DEBUG and TRACE are rarely ever used after 4 or 5 developers have had their hands on it, because turning those on will usually flood the logs with reams and reams of irrelevant messages from unrelated modules, so most people would stop using it after the first time.I think avoiding this problem is one of the major benefits of the proposed std.log design (because vlog output can be filtered on a per-module basis). David
Feb 18 2012
On Thu, Feb 16, 2012 at 7:57 AM, S=F6nke Ludwig <ludwig informatik.uni-luebeck.de> wrote:Am 16.02.2012 10:21, schrieb Jonathan M Davis:yOn Monday, February 13, 2012 16:50:04 David Nadlinger wrote:Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are ver=hewelcome as well!Why does vlog even exist? It's a needless complication IMHO. Let the log levels manage what does and doesn't get logged. I see no reason to add t=ngconcept of verbosity on top of that. It's a needless complication. Also, _please_ add a debug level. Personally, I'd argue for simply copyi=ndsyslog's levels and matching them, since ideally any logging on Linux would be going to syslog anyway. But there are good reasons to have messages beyo=ryinfo. I sure wouldn't want _all_ messages which don't indicate a problem in the app to be marked as info. For instance, what if I want to have info displayed in release mode but want greater verbosity in debug mode? I'd need another log level which isn't there. Using the concept of verbosity to t=diately */and handle this is a needless complication. syslog has #define LOG_EMERG =A0 =A0 =A0 0 =A0 =A0 =A0 /* system is unusable */ #define LOG_ALERT =A0 =A0 =A0 1 =A0 =A0 =A0 /* action must be taken imme=ndition */#define LOG_CRIT =A0 =A0 =A0 =A02 =A0 =A0 =A0 /* critical conditions */ #define LOG_ERR =A0 =A0 =A0 =A0 3 =A0 =A0 =A0 /* error conditions */ #define LOG_WARNING =A0 =A0 4 =A0 =A0 =A0 /* warning conditions */ #define LOG_NOTICE =A0 =A0 =A05 =A0 =A0 =A0 /* normal but significant co=s#define LOG_INFO =A0 =A0 =A0 =A06 =A0 =A0 =A0 /* informational */ #define LOG_DEBUG =A0 =A0 =A0 7 =A0 =A0 =A0 /* debug-level messages */ And I'd like to at least see notice and debug added.Well in addition to Debug I would also like to see Trace but it's f. ex. hard for me to tell the difference between Info and Notice and their name=do not imply that certain severity order IMO.Yes. I would really like to avoid adding more severities because it complicates the decision the developer needs to make when deciding at which log level to log. This reminds of a situation that came up at a previous employer. A bunch of smart people tried to come up with a policy for deciding at which log level to log a particular message. Let just say that the discussion lasted days and no decision was made. I believe that the only reason why this subject even came up at my previous job is because most logging framework provide hard-coded levels that don't have any semantic difference between them. Interesting talk on the subject: http://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice.htmlSo I see a point in the argument that vlog() allows everyone to be happy without endless numbers =ofpredefined log levels.. however I'm also not quite convinced.AsWhile we're at it, what's the point of dfatal? Why on earth would a _fatal_ condition not be fatal if it were in release mode if it were fatal in debug mode? Is it fatal or not? It seems to me like another needless complication. If you're going to have write, then have writef, not format. Then it's actually consistent with our normal I/O functions. Also, do writef and format automatically append a newline? If so, then they should be writeln and writefln.I think the names should be as short as possible for the common 99% case.=this is not a general purpose stream, I think it is fine to drop the 'ln'=.And the current version that defines info("") as the version that can for=matand info.write("") as the plain string version seems to be quite optimal =inthis regard. In my optinion, more descriptive names would just impair readability here instead of helping. They will be written endless number of times but do n=otinfluence the program flow and should immediately understandable by anyon=ewho sees them. But something like log.warn/logf.warn or log.warn/log.warn=fmight also work if you really want the consistency...As of right now (or in the immediate future) we have: info("%s message", Severity.info); info.write(Severity.info, " message); info.writef("%s message", Severity.info); Thanks! -JoseorRich is a horrible name IMHO. It says nothing about what it actually is =does. I'm not sure what a good name would be (BoolMessage?, LogResult?), but Rich by itself is very confusing and utterly uninformative. And why does Configuration's logger property throw if you set it after a logging call has been made. Is it really that inconceivable that someone would swap out loggers at runtime? Or is the idea that you'd swap out the Configuration? - Jonathan M Davis
Feb 17 2012
On 2/17/12 12:06 PM, Jose Armando Garcia wrote:info("%s message", Severity.info);I think defaulting to formatted stuff may be confusing. Andrei
Feb 17 2012
On Fri, Feb 17, 2012 at 6:48 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 2/17/12 12:06 PM, Jose Armando Garcia wrote:Even if we document this? I mean: info("Info message"); Just works. The one place where is wont just work is with: info("This is an ", Severity.info, " message); But do we think users will do with this without reading one bit of the documentation? And even then we can say RTFM ;). I don't have a strong argument or preference for one over the other.info("%s message", Severity.info);I think defaulting to formatted stuff may be confusing.From my experience I tend to write or log using a format string mainlybecause it is more readable to me and plays nicer with localization frameworks like gettext. Thoughts? -JoseAndrei
Feb 17 2012
Am 17.02.2012 21:48, schrieb Andrei Alexandrescu:On 2/17/12 12:06 PM, Jose Armando Garcia wrote:Do you often log static messages? In my experience the majority of logging calls contains dynamic information and using a format string is the most convenient and readable form (compared to concatenating using multiple arguments). An additional infof(), warnf() etc. would be an acceptable alternative, although not very pretty. But if you'd always have to write info.format() or something similar, then this would be a real turn-off, at least for me.info("%s message", Severity.info);I think defaulting to formatted stuff may be confusing. Andrei
Mar 03 2012
On 3/3/12 5:51 AM, Sönke Ludwig wrote:Am 17.02.2012 21:48, schrieb Andrei Alexandrescu:I think it's fine to default to formatted. Also, it just occurred to me that we can adjust the formatting primitives to leave any "%"s alone if there are no matching arguments. Consider: log.info("100% done!"); This is technically an error, but since D has static knowledge there are no variadics, it could simply output the string. That's faster, too, because no validation of the string is necessary. Thoughts? AndreiOn 2/17/12 12:06 PM, Jose Armando Garcia wrote:Do you often log static messages? In my experience the majority of logging calls contains dynamic information and using a format string is the most convenient and readable form (compared to concatenating using multiple arguments). An additional infof(), warnf() etc. would be an acceptable alternative, although not very pretty. But if you'd always have to write info.format() or something similar, then this would be a real turn-off, at least for me.info("%s message", Severity.info);I think defaulting to formatted stuff may be confusing. Andrei
Mar 03 2012
On 04.03.2012 2:17, Andrei Alexandrescu wrote:On 3/3/12 5:51 AM, Sönke Ludwig wrote:I would say just separate them please. Let it work as writeln/writefln and nobody is hurt. With all manner of magic rules the innocent will catch a bullet sooner or latter. And it's always happens kind of point-blank, when the code is shipped & forgotten. Turning on imagination, e.g. for rarely used stuff: log.warn("100%done for task %s, yet the client timed out", taskName); -- Dmitry OlshanskyAm 17.02.2012 21:48, schrieb Andrei Alexandrescu:I think it's fine to default to formatted. Also, it just occurred to me that we can adjust the formatting primitives to leave any "%"s alone if there are no matching arguments. Consider: log.info("100% done!"); This is technically an error, but since D has static knowledge there are no variadics, it could simply output the string. That's faster, too, because no validation of the string is necessary. Thoughts?On 2/17/12 12:06 PM, Jose Armando Garcia wrote:Do you often log static messages? In my experience the majority of logging calls contains dynamic information and using a format string is the most convenient and readable form (compared to concatenating using multiple arguments). An additional infof(), warnf() etc. would be an acceptable alternative, although not very pretty. But if you'd always have to write info.format() or something similar, then this would be a real turn-off, at least for me.info("%s message", Severity.info);I think defaulting to formatted stuff may be confusing. Andrei
Mar 04 2012
On 3/4/12 3:17 AM, Dmitry Olshansky wrote:I would say just separate them please. Let it work as writeln/writefln and nobody is hurt. With all manner of magic rules the innocent will catch a bullet sooner or latter. And it's always happens kind of point-blank, when the code is shipped & forgotten. Turning on imagination, e.g. for rarely used stuff: log.warn("100%done for task %s, yet the client timed out", taskName);Yah, agreed. Probably calls with no extra arguments should be safe. Andrei
Mar 04 2012
On Thu, Feb 16, 2012 at 7:21 AM, Jonathan M Davis <jmdavisProg gmx.com> wro= te:On Monday, February 13, 2012 16:50:04 David Nadlinger wrote:ePlease post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!Why does vlog even exist? It's a needless complication IMHO. Let the log levels manage what does and doesn't get logged. I see no reason to add th=concept of verbosity on top of that. It's a needless complication.Needless? Man, you really make some "strange" comments. I believe that this is better served by you asking for the motivation for vlog instead of make a useless comment like the one above. The reason why vlog exist is to provide users with the ability to enable/disable logging at a package or module level. Lets say that for a particular load you are seeing that module X is not behaving correctly. The next time you run your application (or you can do this at runtime if you have coded your application correctly) you can enable verbose logging in this module by using the --v and --vmodule command line options. I have tried to explain this in the properties Configuration.maxVerboseLevel and Configuration.verboseFilter. Let me know if it still no clear and if I should expand the documentation.Also, _please_ add a debug level. Personally, I'd argue for simply copyin=gsyslog's levels and matching them, since ideally any logging on Linux wou=ld begoing to syslog anyway. But there are good reasons to have messages beyon=dinfo. I sure wouldn't want _all_ messages which don't indicate a problem =inthe app to be marked as info. For instance, what if I want to have info displayed in release mode but want greater verbosity in debug mode?debug info("More information in debug mode"); I think it is very helpful that instead of just suggestion more level we try to see how we can use this module and the power of D to do what you want. If we find that it is not possible or clunky then we can talk about adding more functionality.I'd need another log level which isn't there. Using the concept of verbosity to tr=y andhandle this is a needless complication. syslog has #define LOG_EMERG =A0 =A0 =A0 0 =A0 =A0 =A0 /* system is unusable */ #define LOG_ALERT =A0 =A0 =A0 1 =A0 =A0 =A0 /* action must be taken immed=iately */#define LOG_CRIT =A0 =A0 =A0 =A02 =A0 =A0 =A0 /* critical conditions */ #define LOG_ERR =A0 =A0 =A0 =A0 3 =A0 =A0 =A0 /* error conditions */ #define LOG_WARNING =A0 =A0 4 =A0 =A0 =A0 /* warning conditions */ #define LOG_NOTICE =A0 =A0 =A05 =A0 =A0 =A0 /* normal but significant con=dition */#define LOG_INFO =A0 =A0 =A0 =A06 =A0 =A0 =A0 /* informational */ #define LOG_DEBUG =A0 =A0 =A0 7 =A0 =A0 =A0 /* debug-level messages */ And I'd like to at least see notice and debug added. While we're at it, what's the point of dfatal? Why on earth would a _fata=l_condition not be fatal if it were in release mode if it were fatal in deb=ugmode? Is it fatal or not? It seems to me like another needless complicati=on.Barely a complication. dfatal looks as follow: debug alias log!(Severity.fatal) dfatal; /// ditto else alias log!(Severity.critical) dfatal; /// dittoIf you're going to have write, then have writef, not format. Then it's actually consistent with our normal I/O functions.Good suggestion. Will do.Also, do writef and format automatically append a newline? If so, then they should be writeln and writefln.Technically, no. The module was abstracted with a frontend and a backend. At a very high-level the front does filtering based on compile time and run time configuration options. The backend is basically responsible for persisting messages. It just happens that the only backend implementation that we have writes to a human consumable file hence the newline but it is possible that users are going to want to store this data in persistent storage where each logging event is not separated by a newline.Rich is a horrible name IMHO. It says nothing about what it actually is o=rdoes. I'm not sure what a good name would be (BoolMessage?, LogResult?), =butRich by itself is very confusing and utterly uninformative.Yeah. I don't like Rich. Let me think about a better name. Thanks for the suggestions!And why does Configuration's logger property throw if you set it after a logging call has been made. Is it really that inconceivable that someone =wouldswap out loggers at runtime? Or is the idea that you'd swap out the Configuration?The idea is not to swap out the Configuration but to instead be able to reset each property. There is no technical reason why you can't replace the Logger. I just didn't think this is something the users would want to do in practice. Again this goes beyond technical reason is more of the operational consequence if you allow this. For example: 1. You started logging to /tmp/application/...log... 2. You swapped the logger at runtime to start logging to syslog You have a bunch of important data in /tmp/application/...log... what are you going to do with it? Think of this like a stream flowing into a lake and at some point you want to route the stream to the ocean. What is the state of the lake after the routing change? I would also like to add that this is a restriction that we can remove in the future. I am honestly a little hesitant to remove it now without giving it a little bit of more thought. Thoughts? Thanks! -Jose- Jonathan M Davis
Feb 17 2012
On 2/13/2012 7:50 AM, David Nadlinger wrote:Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!This is a general comment, not specific to std.log: All new library submissions need to be reviewed for applicability of: safe const pure nothrow for all user-facing API functions.
Feb 17 2012
On Fri, Feb 17, 2012 at 7:12 PM, Walter Bright <newshound2 digitalmars.com> wrote:On 2/13/2012 7:50 AM, David Nadlinger wrote:Yep. I have been following that thread and your commits. I have a TODO for this. Thanks. -JosePlease post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well!This is a general comment, not specific to std.log: All new library submissions need to be reviewed for applicability of: safe const pure nothrow for all user-facing API functions.
Feb 17 2012
Since I'm D n00b I'll just post a couple of observations: * I agree that it is a good idea just to use few log levels. * I think is it is a misstake not to let formatting of the whole log message be pluggable (i.e. not the free text message the programmer writes). If I have created a special RFC5424 formatter (with MSGID and STRUCTURED-DATA fields set according to the will of my corporate masters) I want to resuse it in both the FileLogger and a future TcpLogger without having to use inheritance. Your "line format" formatter in FileLogger is a good default formatter though. ///Kalle
Feb 27 2012
On Monday, 27 February 2012 at 18:10:15 UTC, Kalle Svensson wrote:* I agree that it is a good idea just to use few log levels. * I think is it is a misstake not to let formatting of the whole log message be pluggable (i.e. not the free text message the programmer writes). If I have created a special RFC5424 formatter (with MSGID and STRUCTURED-DATA fields set according to the will of my corporate masters) I want to resuse it in both the FileLogger and a future TcpLogger without having to use inheritance. Your "line format" formatter in FileLogger is a good default formatter though.I second what Kalle Svensson is saying. My belief is that when there are many log levels, people don't use them as intended or only use a subset of them, often a combination. / Mikael
Mar 01 2012
On Thu, Mar 01, 2012 at 10:09:28AM +0100, Mikael Lindsten wrote:On Monday, 27 February 2012 at 18:10:15 UTC, Kalle Svensson wrote:[...]* I agree that it is a good idea just to use few log levels.I second what Kalle Svensson is saying. My belief is that when there are many log levels, people don't use them as intended or only use a subset of them, often a combination.[...] I used to think that the more log levels, the better. But later, based on what I observe in real-life projects, I see that most people don't bother trying to figure out what each log level means (they are too lazy / busy to read the docs) so they just randomly pick one that "sounds right" (which usually is equal to "totally wrong"). Let this happen for a few iterations of the software, and you end up with so many wrong level messages that the whole log level system basically becomes useless. This problem gets worse proportionally to the number of people on the project. T -- What's a "hot crossed bun"? An angry rabbit.
Mar 01 2012
On Thu, Mar 1, 2012 at 6:38 AM, H. S. Teoh <hsteoh quickfur.ath.cx> wrote:On Thu, Mar 01, 2012 at 10:09:28AM +0100, Mikael Lindsten wrote:Agreed. I have recently extended this to hierarchy. Most of the time you don't want to deal with the complexity of using and configuring a hierarchical logger. Most programs/system want to enable logging across the board. From my experience is only in very critical areas where you want to increase and decrease logging for that component. An example that comes to mind are inputs and outputs to a system/program. Which may be expensive to log in production but which you want to record during testing. This is why the library includes vlog. To allow the developer and system admin to increase logging for a specific module. Thanks, -JoseOn Monday, 27 February 2012 at 18:10:15 UTC, Kalle Svensson wrote:[...]* I agree that it is a good idea just to use few log levels.I second what Kalle Svensson is saying. My belief is that when there are many log levels, people don't use them as intended or only use a subset of them, often a combination.[...] I used to think that the more log levels, the better. But later, based on what I observe in real-life projects, I see that most people don't bother trying to figure out what each log level means (they are too lazy / busy to read the docs) so they just randomly pick one that "sounds right" (which usually is equal to "totally wrong"). Let this happen for a few iterations of the software, and you end up with so many wrong level messages that the whole log level system basically becomes useless. This problem gets worse proportionally to the number of people on the project.T -- What's a "hot crossed bun"? An angry rabbit.
Mar 06 2012
On Mon, Feb 27, 2012 at 10:10 AM, Kalle Svensson <kalle ieee.org> wrote:Since I'm D n00b I'll just post a couple of observations: * I agree that it is a good idea just to use few log levels. * I think is it is a misstake not to let formatting of the whole log message be pluggable (i.e. not the free text message the programmer writes). If I have created a special RFC5424 formatter (with MSGID and STRUCTURED-DATA fields set according to the will of my corporate masters) I want to resuse it in both the FileLogger and a future TcpLogger without having to use inheritance. Your "line format" formatter in FileLogger is a good default formatter though.I agree but I am some what hesitant to add this now as it will just prolongs everything. I think we can add this in the future without breaking compatibility with code that was written against it.=A0 =A0///Kalle
Mar 06 2012
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.
Feb 29 2012
On Feb 29, 2012, at 4:13 PM, Richard van Scheijen 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.=20 This creates the following matrix: =20 KC KE BF Severity =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =20 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.=20 When a severity should only be handled by a debugger, the normal debug =statement should be used. This is in essence a 4th bit. This is a really great breakdown of the log levels. I've never seen it = explained so clearly. As a counterpoint, the important distinction I've = found is primarily regarding what person should see a particular log = line, and then only differentiated between INFO and ERROR messages. = Roughly: * Developer-Trace * Developer-Info * Developer-Error * Admin-Info * Admin-Error * All-Fatal Typically, the Developer and Admin logs go to different locations, in = which case the Admin log lines may be duplicated in the Developer logs = to provide added context. In any case, what I've found is that with = more than a few log levels, people typically don't know how to classify = things, severity becomes arbitrary, and log-levels are rendered largely = useless. So from the above, we have four severities: Trace, Info, = Error, and Fatal, with flags to indicate what type of message is being = logged: Developer or Admin (aka. User).=
Mar 01 2012
On Wed, 29 Feb 2012 18:13:30 -0600, 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.vote++ I think establishing a good guideline as to log usage should be part of std.log's documentation. Making the bitflags a part of Severity might help cement this concept. It would also allow self documenting code, like: log!(knownCause|unknownEffect|breaksFlow)("This is a severe message.");
Mar 01 2012
On Thu, Mar 01, 2012 at 08:24:31PM -0600, Robert Jacques wrote:On Wed, 29 Feb 2012 18:13:30 -0600, Richard van Scheijen <dlang mesadu.net> wrote:+1. I like this *much* better than "info", "notice", ... etc. T -- "I'm not childish; I'm just in touch with the child within!" - RLWhen 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.vote++ I think establishing a good guideline as to log usage should be part of std.log's documentation. Making the bitflags a part of Severity might help cement this concept. It would also allow self documenting code, like: log!(knownCause|unknownEffect|breaksFlow)("This is a severe message.");
Mar 02 2012
log!(knownCause|unknownEffect|breaksFlow)("This is a severe message.");Simply defining log level enum in terms of this bit field would help a lot. Like, what is the first thing I do when getting a new log lib? Checking all pre-defined log levels and deciding when to use them. And, woah, here it is, subtle but formal guide for use cases!
Mar 03 2012
On Thu, Mar 1, 2012 at 6:24 PM, Robert Jacques <sandford jhu.edu> wrote:On Wed, 29 Feb 2012 18:13:30 -0600, Richard van Scheijen <dlang mesadu.ne=t>wrote:pWhen 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal 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.vote++ I think establishing a good guideline as to log usage should be part of std.log's documentation. Making the bitflags a part of Severity might hel=cement this concept. It would also allow self documenting code, like: log!(knownCause|unknownEffect|breaksFlow)("This is a severe message.");Alluded to this before. My concern with this is that order is not clear from the usage. And if we want to configure logging with a mechanism that doesn't support ordering that means that the user will need 3 knobs to configure each with 3 possible values. Thanks, -Jose
Mar 06 2012
On Tue, 06 Mar 2012 11:34:21 -0600, Jose Armando Garcia <jsancio gmail.com> wrote:On Thu, Mar 1, 2012 at 6:24 PM, Robert Jacques <sandford jhu.edu> wrote:The corollary to this is that causation is not clear from order. As I posted in the other thread, I don't see a conflict between standardized descriptive flags and a total ordering; in fact I think the flags help to define the total ordering and improve logging consistency.On Wed, 29 Feb 2012 18:13:30 -0600, Richard van Scheijen <dlang mesadu.net> wrote:Alluded to this before. My concern with this is that order is not clear from the usage. And if we want to configure logging with a mechanism that doesn't support ordering that means that the user will need 3 knobs to configure each with 3 possible values. Thanks, -JoseWhen 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.vote++ I think establishing a good guideline as to log usage should be part of std.log's documentation. Making the bitflags a part of Severity might help cement this concept. It would also allow self documenting code, like: log!(knownCause|unknownEffect|breaksFlow)("This is a severe message.");
Mar 06 2012
On Wed, Feb 29, 2012 at 4:13 PM, Richard van Scheijen <dlang mesadu.net> wr= ote: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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal A known cause is when the developer knows why a log event is made. e.g.: =ifyou cannot open a file, you do not know why. A known effect is when he/she knows what happens after. Basically, you ca=ntell 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 (=3D 3^3) configuration combinations. To implement this we need 3 configuration nobs with 3 values (on, off, both). Thoughts? -Jose
Mar 06 2012
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: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?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
Mar 06 2012
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.co=m>wrote:eOn 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 th=edeveloper has about the code. This can be done with a 3 bit field. Thes=:are: known-cause, known-effect and breaks-flow. This creates the following matrix: KC KE BF Severity =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal A known cause is when the developer knows why a log event is made. e.g.=thThere 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 wi=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 (=3D 3^3) configuration combinations. To implement this we need 3 configuration nobs with 3 values (on, off, both). Thoughts? -Josea combinatorial approach, shouldn't it be 2^8 =3D 256, not 3^3 =3D 27 val=ues? 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.
Mar 06 2012
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: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.On Tue, 06 Mar 2012 11:01:19 -0600, Jose Armando Garcia <jsancio gmail.com> wrote: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.On Wed, Feb 29, 2012 at 4:13 PM, Richard van Scheijen <dlang mesadu.net> wrote: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?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
Mar 06 2012
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.co=m>wrote:t>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.ne=uwrote: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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal 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, yo=gcan tell if it is a catch-all by this flag. When a severity should only be handled by a debugger, the normal debu=)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 (=3D 3^3=alues?configuration combinations. To implement this we need 3 configuration nobs with 3 values (on, off, both). Thoughts? -JoseThere 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 =3D 256, not 3^3 =3D 27 v=e.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.=// Automatically set logging levels using the standard severity ordering config.minSeverity(Severity.Warning); // Manually set the logging levels config.setSeverities(Severity.Warning| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Severity.Error| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Severity.Critical| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Severity.Severe| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Severity.Fatal); I don't see the problem with including both methods and a large advantage=tohaving 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.
Mar 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: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.On Tue, 06 Mar 2012 11:44:13 -0600, Jose Armando Garcia <jsancio gmail.com> wrote: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.On Tue, Mar 6, 2012 at 9:32 AM, Robert Jacques <sandford jhu.edu> wrote: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.On Tue, 06 Mar 2012 11:01:19 -0600, Jose Armando Garcia <jsancio gmail.com> wrote: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.On Wed, Feb 29, 2012 at 4:13 PM, Richard van Scheijen <dlang mesadu.net> wrote: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?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
Mar 06 2012
On Tue, Mar 6, 2012 at 2:03 PM, Robert Jacques <sandford jhu.edu> wrote:On Tue, 06 Mar 2012 13:41:32 -0600, Jose Armando Garcia <jsancio gmail.co=m>wrote::On Tue, Mar 6, 2012 at 10:11 AM, Robert Jacques <sandford jhu.edu> wrote=e: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> wrot=tOn 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 tha=ngthe 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal 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 loggi=oinfo events I should probably also log error events. If we go with a mechanism like the one you describe above there is n=norder so the configuration is a little more complicated or verbose I should say. Instead of saying we should log everything "greater" tha=^3)warning the user needs to say that they want to log known-cause, known-effect, breaks-flow events. This mean that there are 27 (=3D 3=nconfiguration combinations. To implement this we need 3 configuratio=innobs with 3 values (on, off, both). Thoughts? -JoseThere are only 8 possible configurations and they are nicely ordered =tterms of severity. So I don't see this as a problem. Also, if you wen=gIn practice, all you'd need to take is a flag with the desired levels. i.e. // Automatically set logging levels using the standard severity orderin=with a combinatorial approach, shouldn't it be 2^8 =3D 256, not 3^3 =3D 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.geconfig.minSeverity(Severity.Warning); // Manually set the logging levels config.setSeverities(Severity.Warning| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Severity.Error| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Severity.Critical| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Severity.Severe| =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Severity.Fatal); I don't see the problem with including both methods and a large advanta=dThis began as a discussion regarding Richard's organization of logging severity. That organization isn't something that can be trivially include=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.at a later date.Please be explicit in what you are requesting... If you have an API even be= tter.
Mar 06 2012
On Tue, 06 Mar 2012 17:20:29 -0600, Jose Armando Garcia <jsancio gmail.com> wrote:On Tue, Mar 6, 2012 at 2:03 PM, Robert Jacques <sandford jhu.edu> wrote:Richard proposed an organizational framework for logging severity, which many people including myself and yourself found valuable. In another thread I proposed a logical extension of this framework to make the logging call self documenting. You criticized both as having being overly complex with regard to setting the runtime severity level, to which I proposed a reasonable counter argument. Your response to the counter argument is to suggest making one aspect of it a possible future extension. ?? This seemed to ignore Richard's original suggestion and the extreme value of having a set of well-documented and standardized logging guidelines so that multiple code monkeys / projects 'play well' together. Better yet, by specifying those levels in terms of their conceptual components at the call site, code reviewers can instantly see the nature of what is being logged, without having to remember what each of those log levels mean. And not having to remember the classifications reduces the radius of comprehension needed to use / review the library (http://pragprog.com/magazines/2010-04/tangled-up-in-tools). P.S. You could also set config options using method chaining / fluent interfaces: config.logWarnings.logErrors.logCriticals.logSevers.logFatals;On Tue, 06 Mar 2012 13:41:32 -0600, Jose Armando Garcia <jsancio gmail.com> wrote:Please be explicit in what you are requesting... If you have an API even better.On Tue, Mar 6, 2012 at 10:11 AM, Robert Jacques <sandford jhu.edu> wrote: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.On Tue, 06 Mar 2012 11:44:13 -0600, Jose Armando Garcia <jsancio gmail.com> wrote: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.On Tue, Mar 6, 2012 at 9:32 AM, Robert Jacques <sandford jhu.edu> wrote: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.On Tue, 06 Mar 2012 11:01:19 -0600, Jose Armando Garcia <jsancio gmail.com> wrote: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.On Wed, Feb 29, 2012 at 4:13 PM, Richard van Scheijen <dlang mesadu.net> wrote: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?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
Mar 06 2012
On Thu, Mar 1, 2012 at 4:59 PM, Sean Kelly <sean invisibleduck.org> wrote:On Feb 29, 2012, at 4:13 PM, Richard van Scheijen wrote:developer has about the code. This can be done with a 3 bit field. These a= re: known-cause, known-effect and breaks-flow.When logging the severity level should convey a certain insight that the=if you cannot open a file, you do not know why.This creates the following matrix: KC KE BF Severity =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 1 =A01 =A00 =A0Trace 0 =A01 =A00 =A0Info 1 =A00 =A00 =A0Notice 0 =A00 =A00 =A0Warning 1 =A01 =A01 =A0Error 0 =A01 =A01 =A0Critical 1 =A00 =A01 =A0Severe 0 =A00 =A01 =A0Fatal A known cause is when the developer knows why a log event is made. e.g.:=an tell if it is a catch-all by this flag.A known effect is when he/she knows what happens after. Basically, you c=tatement should be used. This is in essence a 4th bit.When a severity should only be handled by a debugger, the normal debug s=This is a really great breakdown of the log levels. =A0I've never seen it=explained so clearly. =A0As a counterpoint, the important distinction I've= found is primarily regarding what person should see a particular log line,= and then only differentiated between INFO and ERROR messages. =A0Roughly:* Developer-Trace * Developer-Info * Developer-Error * Admin-Info * Admin-Error * All-Fatal Typically, the Developer and Admin logs go to different locations, in whi=ch case the Admin log lines may be duplicated in the Developer logs to prov= ide added context. =A0In any case, what I've found is that with more than a= few log levels, people typically don't know how to classify things, severi= ty becomes arbitrary, and log-levels are rendered largely useless. =A0So fr= om the above, we have four severities: Trace, Info, Error, and Fatal, with = flags to indicate what type of message is being logged: Developer or Admin = (aka. User). I liked Richard analysis but the truth is that I never needed that may knobs for my logging needs. My thought process goes as follow: I observed a interesting state: 1. Is the program observing external input for which the program can execute around. E.g. parsing error with known default. If this is the case the log warning. 2. Is the program observing a state that can do harm to the system/computer/user. Log error and abort (std.log's fatal level) or throw (std.log's critical level) 3. Is the program observing a state that would be interesting to record for forensic. Log at info. Think of a compiler parsing and generating CPU instructions for a piece of code. If the compiler encounters an error in the code for which it has no way to recover (missing symbol, etc), it logs an error and aborts (exception or assert). If the compiler encounters a type mismatch for which it can implicitly convert then maybe the compiler will log a warning and continue. If the compiler wants to document that it generated objects x, y and z then it can log at info. Thanks, -Jose
Mar 06 2012
"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 FatalMinor nit: if you rearrange it as AllowFlow / KnownEffect / KnownCause Then the description will correspond exactly to their integer values. 111 (7) = Trace 110 (6) = Info 101 (5) = Notice 100 (4) = Warning 011 (3) = Error 010 (2) = Critical 001 (1) = Severe 000 (0) = FatalA 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.
Mar 07 2012
On 2/13/2012 7:50 AM, David Nadlinger wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd3cc8e6f5 Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: - Proof-reading of the docs is required. - Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the NG and ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'd warmly encourage everyone to actively try out the module or compare it with any logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! DavidMy 2 cents from a fairly quick scan of the docs: 1) I'm of the opinion that it should be possible to strip all log code from an app without changing it's behavior. Having log levels that change execution flow is evil. It's it the same class of bad practices as assert expressions having side effects, imho. 2) Apps over a certain size (that tends to not be all that big, a few 10's of thousands of lines) tend to start to need module based logging. This proposal includes a set of log levels that have no concept of modularity and another separate set that do. The distinction seems arbitrary and limiting. 3) The conditional stuff seems cute, but I can't recall ever wanting it in anything I've done before. 4) I don't see an obvious facility for changing log parameters at runtime, unless the intent is to build a paramstring array as if it came from command line parameters and calling parseCommandLine again. use case: long running application that has a configuration api or notices a config file has been updated or whatever. Fairly common behavior. 5) The logger severity symbols part should allow more than single character tokens. IMHO, the default should be the full name of the severity, not just the first character. 6) Is the log system thread safe? I see that it's at least thread aware, but what guarantees are about log entry atomicity? 7) The logger setter docs says it's an error to change the logger after a log message has been emitted. That's going to hurt. It's not at all uncommon for an app to want to log some set of errors before it's potentially had enough time to execute the code that configures the logger. use case: reading a config file to get the logger configuration, but can't process the config file properly. Later, Brad
Mar 02 2012
On Mon, 13 Feb 2012 10:50:04 -0500, David Nadlinger <see klickverbot.at> wrote:There are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Some notes: I dislike that logging affects function execution. In particular, I don't think the logging library should have any business throwing exceptions or errors. It should be invisible to the application. The equivalent function can be had by giving a wrapper function (i.e. log this message at the fatal level, and then throw an error). A use case I can see is printing several fatal log messages before exiting. 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. Like others have stated, I think vlog is a) confusing, and b) unnecessary. Even reading the docs, I can't understand what it's used for, and why it has such different syntax than the normal logging stuff. I really like the every function, that's a great idea, one that I've manually implemented (at least the once every N times) many times. Do we have to make the logger a singleton? I'd like to see cases where I can have different log instances. For example, an instance I can enable/disable per class type, or an instance that logs to a diffferent backend. Or a non-shared instance which does not need to handle threading issues (i.e. a per-thread file log). Does this help with the vlog issue? -Steve
Mar 05 2012
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.Like others have stated, I think vlog is a) confusing, and b) unnecessary. Even reading the docs, I can't understand what it's used for, and why it has such different syntax than the normal logging stuff.I think this been modelled after glog's verbose logging support [1], just like much of the rest of the design (by the way, I think a note about this should added somewhere in the module docs). Does the feature as described in the glog docs make sense to you?I really like the every function, that's a great idea, one that I've manually implemented (at least the once every N times) many times.I love it too, a similar design served me really well in some larger *shudder* ActionScript projects. David [1] http://google-glog.googlecode.com/svn/trunk/doc/glog.html#verbose
Mar 05 2012
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=n =better symbol for logging than just 'info', which could be a symbol i=ng =a myriad of places. Given that D's symbol lookup rules allow shadowi=e =of global symbols, this does not work out very well.Originally, the code used log!info and so on, but it was changed to th=current design right after review begin, the rationale being that you ==could always use =C2=BBimport log =3D std.log=C2=AB if you want the ex=tra 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 }Like others have stated, I think vlog is a) confusing, and b) =d =unnecessary. Even reading the docs, I can't understand what it's use=ff.for, and why it has such different syntax than the normal logging stu=I think this been modelled after glog's verbose logging support [1], =just like much of the rest of the design (by the way, I think a note =about this should added somewhere in the module docs). Does the featur=e =as described in the glog docs make sense to you?It's good to know the root of where this comes from. The docs in glog d= o = make more sense than the vlog docs. This may be a doc issue. I'll have to think about it some more. -Steve
Mar 05 2012
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: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;On Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrote: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 }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.
Mar 05 2012
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:=a =The log aliases use names that are too common. I think log.info is==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 =t =the current design right after review begin, the rationale being tha=the extra =you could always use =C2=BBimport log =3D std.log=C2=AB if you want =t =That is not a counter-argument to something related to this library bu=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 }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 pa=rt =of phobos, standard library. Which requires everyone to adopt. When yo=u =see codes like this (below), you don't blame standard library designer=s =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. Couple this with the fact that all of these are nouns -- likely candidat= es = for fields. Your argument has some merit, but I would add that my argument is only = against *common* global namespace names. Another solution besides using a namespace is to make the names less = common, like linfo instead of just info. -Steve
Mar 05 2012
On Tuesday, 6 March 2012 at 01:30:41 UTC, Steven Schveighoffer wrote: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. Couple this with the fact that all of these are nouns -- likely candidates for fields. Your argument has some merit, but I would add that my argument is only against *common* global namespace names. Another solution besides using a namespace is to make the names less common, like linfo instead of just info.I have no objections against changing names. For example, instead of "info" i use "note" for my logger. Not 100% sure about "error" but i think "warning" also implies logging and don't see any use case where it would be used as a variable name.
Mar 05 2012
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:aOn 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. =A0I think log.info is=n abetter symbol for logging than just 'info', which could be a symbol i=ng ofmyriad of places. =A0Given that D's symbol lookup rules allow shadowi=eglobal symbols, this does not work out very well.Originally, the code used log!info and so on, but it was changed to th=couldcurrent design right after review begin, the rationale being that you =e.always use =BBimport log =3D std.log=AB if you want the extra namespac=seeThat doesn't help. =A0Software isn't static. import std.log; import other; // defines B class A : B { =A0 void foo() =A0 { =A0 =A0 =A0info("some info message"); // error! int isn't a function! =A0 } } other.d: class B { =A0 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 =ou?codes like this (below), you don't blame standard library designers do y=ryusing namespace std; int cout;Except 'info', 'error', 'warning' are all common names, likely to be a ve=attractive name for something that has nothing to do with (or cares about=)logging. =A0cout 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 shouldCouple this with the fact that all of these are nouns -- likely candidate=sfor fields. Your argument has some merit, but I would add that my argument is only against *common* global namespace names. Another solution besides using a namespace is to make the names less comm=on,like linfo instead of just info. -Steve
Mar 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 =e:<see klickverbot.at> wrote:On Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrot=is =The log aliases use names that are too common. I think log.info =ol =a better symbol for logging than just 'info', which could be a symb=in a myriad of places. Given that D's symbol lookup rules allow =o =shadowing of global symbols, this does not work out very well.Originally, the code used log!info and so on, but it was changed t==the current design right after review begin, the rationale being that =space.you could always use =BBimport log =3D std.log=AB if you want the extra name=butThat 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 ==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 =do =you see codes like this (below), you don't blame standard library designers =a =you? using namespace std; int cout;Except 'info', 'error', 'warning' are all common names, likely to be =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 shouldD doesn't have a cout, in stdio or elsewhere.
Mar 06 2012
On Tue, 06 Mar 2012 14:32:37 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Mon, Mar 5, 2012 at 5:30 PM, Steven Schveighoffer <schveiguy yahoo.com> wrote:Like Robert says, cout is not in std.stdio. (maybe you were thinking of stdout?) namespaces to clarify common words (*System*.out and *Console*.Out). These only work because they must be identified by the fully qualified name. -SteveExcept '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
Mar 07 2012
On Tuesday, March 06, 2012 02:22:05 so wrote: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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better. - Jonathan M Davis
Mar 05 2012
On Tuesday, 6 March 2012 at 01:33:05 UTC, Jonathan M Davis wrote:And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better.Now you got not only "info" but "log" in global namespace :) I think you meant "log.info".
Mar 05 2012
On 2012-03-06 02:32, Jonathan M Davis wrote:On Tuesday, March 06, 2012 02:22:05 so wrote:The user can then alias "log!info" to "info" if he/she wants to. -- /Jacob CarlborgThat 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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better. - Jonathan M Davis
Mar 05 2012
On Tuesday, March 06, 2012 08:46:14 Jacob Carlborg wrote:On 2012-03-06 02:32, Jonathan M Davis wrote:The user can do whatever aliases they want. It's just that we shouldn't unnecessarily use really common names at the top level, since then they'll conflict with a lot of stuff. - Jonathan M DavisOn Tuesday, March 06, 2012 02:22:05 so wrote:The user can then alias "log!info" to "info" if he/she wants to.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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better. - Jonathan M Davis
Mar 05 2012
On 2012-03-06 08:54, Jonathan M Davis wrote:On Tuesday, March 06, 2012 08:46:14 Jacob Carlborg wrote:What I'm trying so say is that if we use the template function the user can get the best of both worlds. -- /Jacob CarlborgOn 2012-03-06 02:32, Jonathan M Davis wrote:The user can do whatever aliases they want. It's just that we shouldn't unnecessarily use really common names at the top level, since then they'll conflict with a lot of stuff. - Jonathan M DavisOn Tuesday, March 06, 2012 02:22:05 so wrote:The user can then alias "log!info" to "info" if he/she wants to.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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better. - Jonathan M Davis
Mar 06 2012
On Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:On 2012-03-06 02:32, Jonathan M Davis wrote:The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?
Mar 06 2012
On Tuesday, March 06, 2012 09:14:16 so wrote:On Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:Yes. My mistake - probably because the time stuff typicall takes such a template argument as string, which would make this log!"info"(msg). However, adding _log_ isn't necessarily bad, given that this is std.log that we're talking about. It's info and the rest that are the problem. - Jonathan M DavisOn 2012-03-06 02:32, Jonathan M Davis wrote: The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?
Mar 06 2012
On Tue, Mar 6, 2012 at 12:25 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, March 06, 2012 09:14:16 so wrote:Seriously everyone. What are we spending some much effort on this? What is wrong with: import log = std.log; log.info("cool"); Thanks, -JoseOn Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:Yes. My mistake - probably because the time stuff typicall takes such a template argument as string, which would make this log!"info"(msg). However, adding _log_ isn't necessarily bad, given that this is std.log that we're talking about. It's info and the rest that are the problem.On 2012-03-06 02:32, Jonathan M Davis wrote: The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?- Jonathan M Davis
Mar 06 2012
On 3/6/12 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");Indeed I think that should be fine. Thanks, Andrei
Mar 06 2012
On Tue, Mar 06, 2012 at 11:45:47AM -0800, Andrei Alexandrescu wrote:On 3/6/12 11:39 AM, Jose Armando Garcia wrote:[...] +1. I think std.log is ready to merge, as is. T -- Questions are the beginning of intelligence, but the fear of God is the beginning of wisdom.Seriously everyone. What are we spending some much effort on this? What is wrong with: import log = std.log; log.info("cool");Indeed I think that should be fine.
Mar 06 2012
On Tue, 06 Mar 2012 14:39:28 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Tue, Mar 6, 2012 at 12:25 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Because naming is important. It's very difficult to change names once something is released. I seriously could care less about implementation (didn't even look at it). That can be fixed. Naming can't.On Tuesday, March 06, 2012 09:14:16 so wrote:Seriously everyone. What are we spending some much effort on this?On Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:Yes. My mistake - probably because the time stuff typicall takes such a template argument as string, which would make this log!"info"(msg). However, adding _log_ isn't necessarily bad, given that this is std.log that we're talking about. It's info and the rest that are the problem.On 2012-03-06 02:32, Jonathan M Davis wrote: The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?What is wrong with: import log = std.log; log.info("cool");What is wrong with import std.log; log.info("cool"); -Steve
Mar 07 2012
On Wed, 07 Mar 2012 07:09:17 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Tue, 06 Mar 2012 14:39:28 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:alternatively: log_info("cool"); linfo("cool"); lginfo("cool"); There are so many choices besides just "info." We should use something else. -SteveOn Tue, Mar 6, 2012 at 12:25 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:Because naming is important. It's very difficult to change names once something is released. I seriously could care less about implementation (didn't even look at it). That can be fixed. Naming can't.On Tuesday, March 06, 2012 09:14:16 so wrote:Seriously everyone. What are we spending some much effort on this?On Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:Yes. My mistake - probably because the time stuff typicall takes such a template argument as string, which would make this log!"info"(msg). However, adding _log_ isn't necessarily bad, given that this is std.log that we're talking about. It's info and the rest that are the problem.On 2012-03-06 02:32, Jonathan M Davis wrote: The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?What is wrong with: import log = std.log; log.info("cool");What is wrong with import std.log; log.info("cool");
Mar 07 2012
On Wed, Mar 7, 2012 at 6:39 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Wed, 07 Mar 2012 07:09:17 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:aOn Tue, 06 Mar 2012 14:39:28 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Tue, Mar 6, 2012 at 12:25 AM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, March 06, 2012 09:14:16 so wrote:On Tuesday, 6 March 2012 at 07:46:14 UTC, Jacob Carlborg wrote:Yes. My mistake - probably because the time stuff typicall takes such =On 2012-03-06 02:32, Jonathan M Davis wrote: The user can then alias "log!info" to "info" if he/she wants to.Again, you are now forcing 2 common names instead of one as it is now. When you instantiate log!info where do you get "info" from?onBecause naming is important. =A0It's very difficult to change names once something is released. =A0I seriously could care less about implementati=template argument as string, which would make this log!"info"(msg). However, adding _log_ isn't necessarily bad, given that this is std.log that we're talking about. It's info and the rest that are the problem.Seriously everyone. What are we spending some much effort on this?Lets flip the question. Why are you against: import log =3D std.log; Thanks, -Jose(didn't even look at it). =A0That can be fixed. =A0Naming can't.alternatively: log_info("cool"); linfo("cool"); lginfo("cool"); There are so many choices besides just "info." =A0We should use something else.What is wrong with: import log =3D std.log; log.info("cool");What is wrong with import std.log; log.info("cool");-Steve
Mar 11 2012
On Mon, 12 Mar 2012 01:26:54 -0400, Jose Armando Garcia <jsancio gmail.com> wrote:On Wed, Mar 7, 2012 at 6:39 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:I'm against having a requirement (or at least a strong suggestion) to import std.log in a certain way other than import std.log. There are a couple problems with this: 1. Almost all code examples in modules use import modulename; They don't have some documentation that says "you should probably import modulename by import modulename = modulename". For an example of this, see http://www.dsource.org/projects/tango/docs/stable/tango.io.Path.html 2. With no guarantees that everyone will use "log" as the symbol (or even use the symbol), you potentially have several files using std.log under different symbols. For example, someone might prefer "logger" or "lg". This just makes things more confusing than is necessary. I'm not actually against using this technique, I'm just against making it standard practice. I feel using a naming scheme which eliminates having to use this trick to be able to keep your existing names and/or use these common names as members would foster more uniform code and usage. That's all. Yes, this is a form of bikeshedding, but it's one of those things that will be difficult to change later. Even just changing the names of the functions which log to something less common, like I stated above, could be worth a lot. I won't vote against the lib if this is my only objection, but I do think it's important. If others don't, well, I guess we'll see what happens. I likely will be using import log = std.log whenever I use it. -SteveOn Wed, 07 Mar 2012 07:09:17 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:Lets flip the question. Why are you against: import log = std.log;What is wrong with import std.log; log.info("cool");alternatively: log_info("cool"); linfo("cool"); lginfo("cool"); There are so many choices besides just "info." We should use something else.
Mar 12 2012
On Mar 11, 2012, at 10:26 PM, Jose Armando Garcia <jsancio gmail.com> wrote:On Wed, Mar 7, 2012 at 6:39 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:Which is the more common case?alternatively: log_info("cool"); linfo("cool"); lginfo("cool"); There are so many choices besides just "info." We should use something else.Lets flip the question. Why are you against: import log = std.log;
Mar 11 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: =20 import log =3D 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?=
Mar 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:o 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, -JoseSeriously everyone. What are we spending some much effort on this? What is wrong with: import log =3D std.log; log.info("cool");Why should the default be unqualified names? =A0Is this simply a desire t=
Mar 06 2012
Sorry. For some reason I thought info was callable directly without the lead= ing log portion.=20 On Mar 6, 2012, at 1:37 PM, Jose Armando Garcia <jsancio gmail.com> wrote:On Tue, Mar 6, 2012 at 12:43 PM, Sean Kelly <sean invisibleduck.org> wrote=:ot change std.log so we can just get it in already?On Mar 6, 2012, at 11:39 AM, Jose Armando Garcia wrote: =20Seriously everyone. What are we spending some much effort on this? What is wrong with: =20 import log =3D std.log; log.info("cool");=20 Why should the default be unqualified names? Is this simply a desire to n==20 What are you proposing? =20 struct Log { static alias log!Severity.info info; ... } =20 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. =20 =20 Thanks, -Jose
Mar 06 2012
On Mon, 05 Mar 2012 19:22:05 -0600, so <so so.so> wrote:On Monday, 5 March 2012 at 23:51:29 UTC, Steven Schveighoffer wrote:Please don't forget that you are _submitting_ a library into Phobos and the D ecosystem at large. Yes, new code can be expected to avoid these names, but all existing code has to be retrofitted and fixed.On Mon, 05 Mar 2012 18:30:03 -0500, David Nadlinger <see klickverbot.at> wrote: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.On Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrote: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 }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.
Mar 05 2012
On Tuesday, 6 March 2012 at 03:11:11 UTC, Robert Jacques wrote:Please don't forget that you are _submitting_ a library into Phobos and the D ecosystem at large. Yes, new code can be expected to avoid these names, but all existing code has to be retrofitted and fixed.Probably it is the reason why they use cryptic variable names in C++ std library :)
Mar 06 2012
On Mon, Mar 5, 2012 at 7:11 PM, Robert Jacques <sandford jhu.edu> wrote:On Mon, 05 Mar 2012 19:22:05 -0600, so <so so.so> wrote:heOn Monday, 5 March 2012 at 23:51:29 UTC, Steven Schveighoffer wrote:Please don't forget that you are _submitting_ a library into Phobos and t=On Mon, 05 Mar 2012 18:30:03 -0500, David Nadlinger <see klickverbot.at> wrote: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.On Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrote:That doesn't help. =A0Software isn't static. import std.log; import other; // defines B class A : B { =A0 void foo() =A0 { =A0 =A0 =A0info("some info message"); // error! int isn't a function! =A0 } } other.d: class B { =A0 int info; // added later }The log aliases use names that are too common. =A0I think log.info is a better symbol for logging than just 'info', which could be a symbol in a myriad of places. =A0Given 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 =BBimport log =3D std.log=AB if you want the extra namespace.D ecosystem at large. Yes, new code can be expected to avoid these names, but all existing code has to be retrofitted and fixed.Not is doesn't. First, it will only break your code if you import std.log. If you are now importing std.log that means you are already modifying the code. If you don't want to modify existing code when adding your changes just: import someSymboleThatDoesntCollide =3D std.log; Pick your poison. Thanks, -Jose
Mar 06 2012
On 3/6/12 11:36 AM, Jose Armando Garcia wrote:import someSymboleThatDoesntCollide = std.log;I think this works better: static import log = std.log; Andrei
Mar 06 2012
On Tuesday, 6 March 2012 at 19:47:50 UTC, Andrei Alexandrescu wrote:On 3/6/12 11:36 AM, Jose Armando Garcia wrote:Isn't this just another case of DMD silently accepting superfluous attributes/modifiers? Davidimport someSymboleThatDoesntCollide = std.log;I think this works better: static import log = std.log;
Mar 06 2012
On Mon, Mar 5, 2012 at 5:32 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, March 06, 2012 02:22:05 so wrote:using namesapce std; matrix vector = new Matrix(...) The variable vector conflicts with std::vector. Honestly, I can sit here and come up with 10s or 100s of example where you want to use a symbol that is expose by another module. You don't have to go far just look at druntime and phobos. This the exact reason why modules and namespace exist and one of the reason why people hate C's preprocessor macros. D solved this problem years ago.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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better.- Jonathan M Davis
Mar 06 2012
On Tue, 06 Mar 2012 14:27:17 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Mon, Mar 5, 2012 at 5:32 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:The not so trivial and important difference is here: using namespace std; That is, the default is, vector is *NOT* imported into your namespace. For D modules, it is. -SteveOn Tuesday, March 06, 2012 02:22:05 so wrote:using namesapce std; matrix vector = new Matrix(...) The variable vector conflicts with std::vector. Honestly, I can sit here and come up with 10s or 100s of example where you want to use a symbol that is expose by another module. You don't have to go far just look at druntime and phobos. This the exact reason why modules and namespace exist and one of the reason why people hate C's preprocessor macros. D solved this problem years ago.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 that cout is not exactly something that would be considered a normal variable name. Something like info _is_. This logging module is taking incredibly common names and shoving them as far into the global namespace as anything can go in D which isn't a compiler built-in. _Not_ a good idea IMHO - not without good reason. And I really don't think that this merits it. log!info(msg) would work just fine and would be _far_ better.
Mar 07 2012
On Mon, Mar 5, 2012 at 3:51 PM, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Mon, 05 Mar 2012 18:30:03 -0500, David Nadlinger <see klickverbot.at> wrote:aOn Monday, 5 March 2012 at 21:55:08 UTC, Steven Schveighoffer wrote:The log aliases use names that are too common. =A0I think log.info is a better symbol for logging than just 'info', which could be a symbol in =ofmyriad of places. =A0Given that D's symbol lookup rules allow shadowing=uldglobal 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 co=import log =3D std.log;always use =BBimport log =3D std.log=AB if you want the extra namespace.That doesn't help. =A0Software isn't static. import std.log;import other; // defines B class A : B { =A0 void foo() =A0 { =A0 =A0 =A0info("some info message"); // error! int isn't a function!log.info("some info message");=A0 } } other.d: class B { =A0 int info; // added later }d for,Like others have stated, I think vlog is a) confusing, and b) unnecessary. =A0Even reading the docs, I can't understand what it's use=tand why it has such different syntax than the normal logging stuff.I think this been modelled after glog's verbose logging support [1], jus=islike much of the rest of the design (by the way, I think a note about th=d inshould added somewhere in the module docs). Does the feature as describe=dothe glog docs make sense to you?It's good to know the root of where this comes from. =A0The docs in glog =make more sense than the vlog docs. This may be a doc issue. =A0I'll have to think about it some more. -Steve
Mar 06 2012
On Mon, Mar 5, 2012 at 1:55 PM, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Mon, 13 Feb 2012 10:50:04 -0500, David Nadlinger <see klickverbot.at> wrote:gsThere are several modules in the review queue right now, and to get thin=l.going, I have volunteered to manage the review of Jose's std.log proposa=n'tBarring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Some notes: I dislike that logging affects function execution. =A0In particular, I do=think the logging library should have any business throwing exceptions or errors. =A0It should be invisible to the application. =A0The equivalent f=unctioncan be had by giving a wrapper function (i.e. log this message at the fat=allevel, and then throw an error). =A0A use case I can see is printing seve=ralfatal log messages before exiting.Then don't use std.log.fatal. It is not like you are forced to use it. You can implement the above by using std.log.errorThe log aliases use names that are too common. =A0I think log.info is a b=ettersymbol for logging than just 'info', which could be a symbol in a myriad =ofplaces. =A0Given that D's symbol lookup rules allow shadowing of global symbols, this does not work out very well.This is a tough one. Should we be relying on D's module abstraction. It is not scalable as a module designer and implementer to think about other modules. This is why a lot of programming languages implement the concept of namespaces. import log =3D std.log; log.info("hello world");Like others have stated, I think vlog is a) confusing, and b) unnecessary=.=A0Even reading the docs, I can't understand what it's used for, and why =ithas such different syntax than the normal logging stuff.I have tried to explain this before but it looks like I have failed. I find it useful. If you are interested on a different explaination: http://google-glog.googlecode.com/svn/trunk/doc/glog.htmlI really like the every function, that's a great idea, one that I've manually implemented (at least the once every N times) many times.Great!Do we have to make the logger a singleton? =A0I'd like to see cases where=Ican have different log instances. =A0For example, an instance I can enable/disable per class type, or an instance that logs to a diffferent backend. =A0Or a non-shared instance which does not need to handle thread=ingissues (i.e. a per-thread file log).=A0Does this help with the vlog issue=?My point of view here is that as a developer I never know how I want to categorize my log during development. Some people use class name as a hack for doing this. What about functional programs that don't use class/objects? What about logical component/classes that span multiple classes? I always found class based grouping for logging as a hack. D made the observation that classes are not always the best abstraction unit so it introduced modules. std.log filters based on modules (actually source files to be exact but if D had __MODULE__, std.log would use that instead.)-Steve
Mar 06 2012
On Tue, 06 Mar 2012 14:19:27 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Mon, Mar 5, 2012 at 1:55 PM, Steven Schveighoffer <schveiguy yahoo.com> wrote:Then I can't access the fatal level. When I used Log4Net to log application errors, I only logged fatal errors to the event log (using an event log backend). In fact, in that case, I was *catching* uncaught exceptions. There was no need to throw another exception at that point. My point is, whether to throw an exception or not should be up to the application, and having a fatal level can be utilized in other ways than "this is just like error but throws an exception". Again, the logging library should not be in the business of dictating application design. If fatal and critical logged an error at the "Error" logging level, and threw an appropriate exception, that would be a different story, because then it's just a convenience function. But you have made two levels of logging unavailable without throwing exceptions. As I brought up in another part of this thread, I envision the following pattern emerging: try { fatal("connection aborted!"); } catch(LoggingError) { } ... // graceful shutdown of rest of the application throw new LoggingError("connection aborted!");On Mon, 13 Feb 2012 10:50:04 -0500, David Nadlinger <see klickverbot.at> wrote:Then don't use std.log.fatal. It is not like you are forced to use it. You can implement the above by using std.log.errorThere are several modules in the review queue right now, and to get things going, I have volunteered to manage the review of Jose's std.log proposal. Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Some notes: I dislike that logging affects function execution. In particular, I don't think the logging library should have any business throwing exceptions or errors. It should be invisible to the application. The equivalent function can be had by giving a wrapper function (i.e. log this message at the fatal level, and then throw an error). A use case I can see is printing several fatal log messages before exiting.The problem is that by default D pulls in a module's symbols into the current scope. You have to go out of your way to *avoid* this. By default you should be able to just import std.log and not have your local symbols shadow std.log's. There are many solutions to this, as I have brought up elsewhere.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.This is a tough one. Should we be relying on D's module abstraction. It is not scalable as a module designer and implementer to think about other modules. This is why a lot of programming languages implement the concept of namespaces.import log = std.log; log.info("hello world");I like this better: import std.log; // alias log.info info // if you desire log.info("hello world");Someone else pointed that out. I think the documentation explanation there is much more complete than your version, and I think vlog is fine, it just needs a lot more documentation.Like others have stated, I think vlog is a) confusing, and b) unnecessary. Even reading the docs, I can't understand what it's used for, and why it has such different syntax than the normal logging stuff.I have tried to explain this before but it looks like I have failed. I find it useful. If you are interested on a different explaination: http://google-glog.googlecode.com/svn/trunk/doc/glog.htmlI wasn't speaking so much about filtering logging based on classes (and BTW, most logging libraries use hierarchical symbols to denote logging instances, they don't necessarily have to follow class names), but simply being able to have multiple log instances. That is, instead of having one global instance of log, what about multiple instances (I don't care if they are named or not). They don't have to be based on some sort of name, just another place you can configure independently of the rest of the application. For example, I may want a log instance in my library that logs to some library log file independent of the full application log. -SteveDo we have to make the logger a singleton? I'd like to see cases where I can have different log instances. For example, an instance I can enable/disable per class type, or an instance that logs to a diffferent backend. Or a non-shared instance which does not need to handle threading issues (i.e. a per-thread file log). Does this help with the vlog issue?My point of view here is that as a developer I never know how I want to categorize my log during development. Some people use class name as a hack for doing this. What about functional programs that don't use class/objects? What about logical component/classes that span multiple classes? I always found class based grouping for logging as a hack. D made the observation that classes are not always the best abstraction unit so it introduced modules. std.log filters based on modules (actually source files to be exact but if D had __MODULE__, std.log would use that instead.)
Mar 07 2012
On Fri, Mar 2, 2012 at 12:56 AM, Brad Roberts <braddr puremagic.com> wrote:On 2/13/2012 7:50 AM, David Nadlinger wrote:gs going, I have volunteered to manage theThere are several modules in the review queue right now, and to get thin=riod starts now and ends in three weeks, onreview of Jose's std.log proposal. Barring any objections, the review pe=0293cbd3cc8e6f5March 6th, followed by a week of voting. --- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a=(will be part of 2.058)Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: =A0- Proof-reading of the docs is required. =A0- Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 =NG and ML archives for "std.log".--- Earlier drafts of this library were discussed last year, just search the=abundance of partly incompatible loggingI think getting this right is vitally important so that we can avoid an =try out the module or compare it with anylibraries like in Java. Thus, I'd warmly encourage everyone to actively =nsive reviews are obviously appreciated, shortlogging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehe=Thanks for looking at the documentation.comments are very welcome as well! DavidMy 2 cents from a fairly quick scan of the docs:1) I'm of the opinion that it should be possible to strip all log code fr=om an app without changing it's behavior.Having log levels that change execution flow is evil. =A0It's it the same=class of bad practices as assert expressionshaving side effects, imho.I think this depends on your point of view. One way to look at critical("critical") is as a replacement to enforce() that logs. We could extends critical in a way similar to enforce where you can specify the exception that should be thrown. David, would this help with the issues you express earlier?2) Apps over a certain size (that tends to not be all that big, a few 10'=s of thousands of lines) tend to start to needmodule based logging. =A0This proposal includes a set of log levels that =have no concept of modularity and anotherseparate set that do. =A0The distinction seems arbitrary and limiting.This distinction is not a limitation of the logger API. It is a limitation of the configuration API. In the future we can add the option to enable error, warning, info at the module level without breaking existing code.3) The conditional stuff seems cute, but I can't recall ever wanting it i=n anything I've done before.4) I don't see an obvious facility for changing log parameters at runtime=, unless the intent is to build a paramstringarray as if it came from command line parameters and calling parseCommand=Line again. =A0use case: long running applicationthat has a configuration api or notices a config file has been updated or=whatever. =A0Fairly common behavior.If you want to change the log level at runtime you can just: std.log.config.minSeverity =3D Severity.info; No need to call parseCommandLine. Everything that parseCommandLine does can be implemented by a client user. Really parseCommandLine doesn't need to be part of the Configuration class. It is just there for grouping and documentation.5) The logger severity symbols part should allow more than single charact=er tokens. =A0IMHO, the default should be thefull name of the severity, not just the first character.My motivation for using one char is that it is easier to parse by both computers and humans. It is also makes the framework faster since it writes less bytes. I think we can extends this and fix this once we have custom line formatted.6) Is the log system thread safe? =A0I see that it's at least thread awar=e, but what guarantees are about log entry atomicity?Yes, it is. It is probably to conservative in this regard. I need to go back and do a lot performances improvements.7) The logger setter docs says it's an error to change the logger after a=log message has been emitted. =A0That's going tohurt. =A0It's not at all uncommon for an app to want to log some set of e=rrors before it's potentially had enough time toexecute the code that configures the logger. =A0use case: reading a confi=g file to get the logger configuration, but can'tprocess the config file properly.This was brought up before. There is no technical reason for this and I will remove it. Thanks!Later, Brad
Mar 06 2012
On Mon, Feb 13, 2012 at 7:50 AM, David Nadlinger <see klickverbot.at> wrote= :There are several modules in the review queue right now, and to get thing=sgoing, I have volunteered to manage the review of Jose's std.log proposal=.Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Hi everyone, I have been tracking all the changes we need to make immediately and things we can add in the future without break backward compatibility if have access to trello go here: https://trello.com/card/std-log/4f33d3c6542c156960533efb/1# Exporting things form trello looks like a pain but here it is: 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(...) 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 Note: There were a few other things that were suggested here that I have already fixed. Need to look at my commits for this. Thanks, -Jose--- Code: https://github.com/jsancio/phobos/commit/d114420e0791c704f6899d81a0293cbd=3cc8e6f5Docs: http://jsancio.github.com/phobos/phobos/std_log.html Known remaining issues: =A0- Proof-reading of the docs is required. =A0- Not yet fully tested on Windows. Depends on: https://github.com/D-Programming-Language/druntime/pull/141 (will be part of 2.058) --- Earlier drafts of this library were discussed last year, just search the =NGand ML archives for "std.log". I think getting this right is vitally important so that we can avoid an abundance of partly incompatible logging libraries like in Java. Thus, I'=dwarmly encourage everyone to actively try out the module or compare it wi=thany logging solution you might already be using in your project. Please post all feedback in this thread, and remember: Although comprehensive reviews are obviously appreciated, short comments are very welcome as well! David
Mar 06 2012
On Mar 6, 2012, at 11:59 AM, Jose Armando Garcia wrote:=20 Future: =20 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(=85)For future enhancements, I'd just reference the docs for Boost.Log :-p=
Mar 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.loggerI 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
Mar 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:tFuture: 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? =A0I think this needs to be figured ou=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, -JoseamFix 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.loggerI still believe pretty strongly that the logger must not affect application flow, ie, not throw or exit the app. =A0From the feed back, I=not alone in thinking that. =A0I don't believe that "well, don't use thos=elog 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
Mar 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:tFuture: 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? =A0I think this needs to be figured ou=before merge, not at some vague future.amFix 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.loggerI still believe pretty strongly that the logger must not affect application flow, ie, not throw or exit the app. =A0From the feed back, I=not alone in thinking that. =A0I don't believe that "well, don't use thos=elog 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
Mar 06 2012
I still don't understand how to set the filename of the log file. Has this been added yet?
Mar 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
Mar 06 2012
On 3/7/12, Jose Armando Garcia <jsancio gmail.com> wrote:http://jsancio.github.com/phobos/phobos/std_log.html#fileNamePrefixesThat was what I was looking for but I didn't find it at first. I think that info about what the defaults are ([program].[hostname].[user].[severity].log.[datetime].[pid]) might be useful somewhere at the top. But that's just my 2 cents..
Mar 06 2012
On Mon, Mar 5, 2012 at 3:26 PM, David Nadlinger <code klickverbot.at> wrote= :Just a quick reply, more tomorrow: On 6 Mar 2012, at 0:03, Jose Armando Garcia wrote:utWhat is your objection here? I don't remember reading your thoughts on critical.Darn, my longer review post apparently didn't make it through the new web interface; hope I can dig it up again=85 Anyway, my main reservations abo=critical are that a CriticalException in my opinion has absolutely no semantic value (compared to e.g. a FileNotFoundException or at least FileException thrown from file I/O code). While I guess it works for programs where you know there is no way you ca=nhandle the exception and just want to do some rudimentary clean up before aborting with a message box/=85, I wouldn't want to let it bubble up thro=ughany of my APIs if I'm writing a library, because there is no way a user c=anknow how to handle it without the semantical meaning being defined (maybe=inthe docs, along the lines of =BBthe program should assume nothing and shu=titself down as quickly as possible=AB or whatever you design intention wa=s).Makes sense?Yep it makes sense. I was thinking about it this morning. My current thinking is to add overloaded methods that look as follow: critical(new Exception(...), "format string", params...) This method records the message, exception and throws the exception specifi= ed. error(new Exception(...), "format string", params...) This method records the message and exception. Everything else well stay the same. In other words if you don't pass an exception to critical then it just throws the default exception: CriticalException. Or our other option is just to throw our hands in the air and decide not to solve this problem. In other words remove Severity.fatal and Severity.critical. Thoughts? -Jose
Mar 06 2012
On Tue, Mar 6, 2012 at 3:27 PM, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 3/7/12, Jose Armando Garcia <jsancio gmail.com> wrote:Yeah. I am not terribly happy how ddoc and dlang.org organizes the documentation. I have been thinking of duplicating a lot of the documentation to the top but I have two main objections that are holding back. 1. document duplication and 2. overloading the user with information. I would like the top of the document with enough information and example for the regular user to just start logging. They can later come back and read the whole thing when they want to configure and tweak things. Thoughts? Thanks, -Josehttp://jsancio.github.com/phobos/phobos/std_log.html#fileNamePrefixesThat was what I was looking for but I didn't find it at first. I think that info about what the defaults are ([program].[hostname].[user].[severity].log.[datetime].[pid]) might be useful somewhere at the top. But that's just my 2 cents..
Mar 06 2012
On Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:On Tue, 6 Mar 2012, Jose Armando Garcia wrote:Agreed. The logging functions should _not_ throw. - Jonathan M DavisFuture: 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.loggerI 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.
Mar 06 2012
On 07/03/12 09:25, Jonathan M Davis wrote:On Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:+1. Is std.log a logging library or a complete error management library? If it's a logging library, the last thing it should be doing is affecting program flow. In the case of fatal, in particular, the program may need to do something else after logging the fatal error before terminating. You could argue that the program should do that before logging the fatal error, but I don't think that's nice semantics. On the other hand, if it's a complete error management library, it probably shouldn't be called std.log. That's my opinion as an uninformed user. GeoffOn Tue, 6 Mar 2012, Jose Armando Garcia wrote:Agreed. The logging functions should _not_ throw.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.loggerI 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.
Mar 06 2012
On 3/6/12 4:31 PM, Geoffrey Biggs wrote:On 07/03/12 09:25, Jonathan M Davis wrote:I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful. AndreiOn Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:+1. Is std.log a logging library or a complete error management library? If it's a logging library, the last thing it should be doing is affecting program flow. In the case of fatal, in particular, the program may need to do something else after logging the fatal error before terminating. You could argue that the program should do that before logging the fatal error, but I don't think that's nice semantics. On the other hand, if it's a complete error management library, it probably shouldn't be called std.log.On Tue, 6 Mar 2012, Jose Armando Garcia wrote:Agreed. The logging functions should _not_ throw.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.loggerI 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.
Mar 06 2012
On Tuesday, March 06, 2012 16:59:09 Andrei Alexandrescu wrote:I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.I think that it would be far more meaningful to have a logging function which you pass the exception to throw. That way, you can throw whatever is appropriate for your program, not have std.log throw a logging exception of some kind. Such a function would be a convenience function where the programmer is explicitly saying that they want to log and then throw rather than having logging functions throw as a matter of course if the logging level is critical enough. What if you want to log such a message _without_ throwing? As it stands, std.log is conflating two separate concepts - logging and and error handling. Providing a convenience function to make that easier is fine, but making it so that the normal logging functions deal with error handling is not. - Jonathan M Davis
Mar 06 2012
On 3/6/12 5:07 PM, Jonathan M Davis wrote:As it stands, std.log is conflating two separate concepts - logging and and error handling.Throwing an exception is not error handling. If it were, so many entities would do so, the whole concept would become devoid of meaning. Andrei
Mar 06 2012
On 07/03/12 09:59, Andrei Alexandrescu wrote:I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.That approach means that if I actually do have a fatal error, I can't mark it as such. It gets conflated with the non-fatal errors, both in the source and in the logging output (which may, for example, be filtering for fatal errors to phone someone in the middle of the night while errors just send an email). Another point worth considering is that I cannot use the fatal level and be able to re-compile my software with logging disabled, because that will change the program flow. Forcing the two semantic concepts (logging and error handling) together needlessly restricts the ways the library can be used. It is nice to encapsulate frequent patterns, but providing a convenience function that throws an error, or a new level ("terminate" or something) is a better approach than forcing that pattern on everyone. Based on the name, it's a *logging* library, not an error handling library. Geoff
Mar 06 2012
On 3/6/12 6:05 PM, Geoffrey Biggs wrote:That approach means that if I actually do have a fatal error, I can't mark it as such.Use log.fatal for those. Andrei
Mar 06 2012
On Tue, 06 Mar 2012 21:22:21 -0600, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/6/12 6:05 PM, Geoffrey Biggs wrote:But fatal "Logs a fatal severity message. Fatal log messages terminate the application after the message is persisted. Fatal log message cannot be disable at compile time or at run time." The point is that he want to log a fatal message and then terminate in a custom manner. I don't see a problem with convince functions that log and error and then throw, but not having the option to not throw is an unnecessary limitation.That approach means that if I actually do have a fatal error, I can't mark it as such.Use log.fatal for those. Andrei
Mar 07 2012
On Wed, Mar 7, 2012 at 7:16 AM, Robert Jacques <sandford jhu.edu> wrote:On Tue, 06 Mar 2012 21:22:21 -0600, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Okay. Let me say this one last time. If you don't want to assert or throw don't use fatal and critical. I think we are done beating a dead horse. Maybe it is not clear from the documentation but the only reason why fatal and critical exist is because of their assert and throw semantic. This is also the reason why you can't disable them. I understand that to a person that has not read the documentation is may not be clear to them that fatal("message") asserts and critical("message") throws. Knowing this observation maybe we can remove these severities and make the behavior more obvious by adding the tempalte logAndThrow. Thanks, -JoseOn 3/6/12 6:05 PM, Geoffrey Biggs wrote:But fatal "Logs a fatal severity message. Fatal log messages terminate the application after the message is persisted. Fatal log message cannot be disable at compile time or at run time." The point is that he want to log a fatal message and then terminate in a custom manner. I don't see a problem with convince functions that log and error and then throw, but not having the option to not throw is an unnecessary limitation.That approach means that if I actually do have a fatal error, I can't mark it as such.Use log.fatal for those. Andrei
Mar 11 2012
On Mon, 12 Mar 2012 00:15:14 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:On Wed, Mar 7, 2012 at 7:16 AM, Robert Jacques <sandford jhu.edu> wrote:There is a strong impression that a 'fatal' error and an 'error' will appear differently in the log file. So long as fatal is anything more than log an error, flush and throw, there will be people wanting to separate the fatal log level from fatal log and throw command. I think the logAndThrow will clear up this confusion.On Tue, 06 Mar 2012 21:22:21 -0600, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Okay. Let me say this one last time. If you don't want to assert or throw don't use fatal and critical. I think we are done beating a dead horse. Maybe it is not clear from the documentation but the only reason why fatal and critical exist is because of their assert and throw semantic. This is also the reason why you can't disable them. I understand that to a person that has not read the documentation is may not be clear to them that fatal("message") asserts and critical("message") throws. Knowing this observation maybe we can remove these severities and make the behavior more obvious by adding the tempalte logAndThrow. Thanks, -JoseOn 3/6/12 6:05 PM, Geoffrey Biggs wrote:But fatal "Logs a fatal severity message. Fatal log messages terminate the application after the message is persisted. Fatal log message cannot be disable at compile time or at run time." The point is that he want to log a fatal message and then terminate in a custom manner. I don't see a problem with convince functions that log and error and then throw, but not having the option to not throw is an unnecessary limitation.That approach means that if I actually do have a fatal error, I can't mark it as such.Use log.fatal for those. Andrei
Mar 12 2012
On Mon, Mar 12, 2012 at 1:11 PM, Robert Jacques <sandford jhu.edu> wrote:On Mon, 12 Mar 2012 00:15:14 -0500, Jose Armando Garcia <jsancio gmail.com> wrote:Okay. Let me try to wipe something up soonish but it may take me some time given my current schedule.On Wed, Mar 7, 2012 at 7:16 AM, Robert Jacques <sandford jhu.edu> wrote:There is a strong impression that a 'fatal' error and an 'error' will appear differently in the log file. So long as fatal is anything more than log an error, flush and throw, there will be people wanting to separate the fatal log level from fatal log and throw command. I think the logAndThrow will clear up this confusion.On Tue, 06 Mar 2012 21:22:21 -0600, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:Okay. Let me say this one last time. If you don't want to assert or throw don't use fatal and critical. I think we are done beating a dead horse. Maybe it is not clear from the documentation but the only reason why fatal and critical exist is because of their assert and throw semantic. This is also the reason why you can't disable them. I understand that to a person that has not read the documentation is may not be clear to them that fatal("message") asserts and critical("message") throws. Knowing this observation maybe we can remove these severities and make the behavior more obvious by adding the tempalte logAndThrow. Thanks, -JoseOn 3/6/12 6:05 PM, Geoffrey Biggs wrote:But fatal "Logs a fatal severity message. Fatal log messages terminate the application after the message is persisted. Fatal log message cannot be disable at compile time or at run time." The point is that he want to log a fatal message and then terminate in a custom manner. I don't see a problem with convince functions that log and error and then throw, but not having the option to not throw is an unnecessary limitation.That approach means that if I actually do have a fatal error, I can't mark it as such.Use log.fatal for those. Andrei
Mar 12 2012
On Tue, Mar 6, 2012 at 6:05 PM, Geoffrey Biggs <geoffrey.biggs aist.go.jp> wrote:On 07/03/12 09:59, Andrei Alexandrescu wrote:Fatal and Critical severity cannot be disabled either at runtime or at compile. In other words fatal log messages will always assert(true) and critical log messages will always throw.I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.That approach means that if I actually do have a fatal error, I can't mark it as such. It gets conflated with the non-fatal errors, both in the source and in the logging output (which may, for example, be filtering for fatal errors to phone someone in the middle of the night while errors just send an email). Another point worth considering is that I cannot use the fatal level and be able to re-compile my software with logging disabled, because that will change the program flow.Forcing the two semantic concepts (logging and error handling) together needlessly restricts the ways the library can be used. It is nice to encapsulate frequent patterns, but providing a convenience function that throws an error, or a new level ("terminate" or something) is a better approach than forcing that pattern on everyone. Based on the name, it's a *logging* library, not an error handling library.Fatal and critical are these convenience functions.Geoff
Mar 06 2012
On Tue, Mar 6, 2012 at 5:07 PM, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, March 06, 2012 16:59:09 Andrei Alexandrescu wrote:This exactly how I am thinking of extending critical. I don't have an API yet but the intent is that you can pass an exception to critical and the module will throw it for you. Very similar to how enforce works.I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.I think that it would be far more meaningful to have a logging function which you pass the exception to throw.That way, you can throw whatever is appropriate for your program, not have std.log throw a logging exception of some kind. Such a function would be a convenience function where the programmer is explicitly saying that they want to log and then throw rather than having logging functions throw as a matter of course if the logging level is critical enough. What if you want to log such a message _without_ throwing?I think we are going around in circles. If you don't want to abort or throw then use error.As it stands, std.log is conflating two separate concepts - logging and and error handling. Providing a convenience function to make that easier is fine, but making it so that the normal logging functions deal with error handling is not.Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things. Thanks, -Jose- Jonathan M Davis
Mar 06 2012
On 07/03/12 11:12, Jose Armando Garcia wrote:On Tue, Mar 6, 2012 at 6:05 PM, Geoffrey Biggs <geoffrey.biggs aist.go.jp> wrote:OK, I took another look at the docs. I see your point now. Sorry for making a fuss. However, I think that in this case, the log levels usable without killing the program are too coarse. This may be a matter of taste, though. GeoffThat approach means that if I actually do have a fatal error, I can't mark it as such. It gets conflated with the non-fatal errors, both in the source and in the logging output (which may, for example, be filtering for fatal errors to phone someone in the middle of the night while errors just send an email). Another point worth considering is that I cannot use the fatal level and be able to re-compile my software with logging disabled, because that will change the program flow.Fatal and Critical severity cannot be disabled either at runtime or at compile. In other words fatal log messages will always assert(true) and critical log messages will always throw.Forcing the two semantic concepts (logging and error handling) together needlessly restricts the ways the library can be used. It is nice to encapsulate frequent patterns, but providing a convenience function that throws an error, or a new level ("terminate" or something) is a better approach than forcing that pattern on everyone. Based on the name, it's a *logging* library, not an error handling library.Fatal and critical are these convenience functions.
Mar 06 2012
On Tue, 06 Mar 2012 19:59:09 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/6/12 4:31 PM, Geoffrey Biggs wrote:I think access to the fatal/critical logging level should not be coupled with throwing exceptions. I have no problem with having critical or fatal convenience functions that throw and log, but it should not be a *requirement*, and it should not be the default. I'd combine these two levels into one (there is no semantic difference except one throws an exception and one throws an error), and if I got my way, log.critical(...) would log a message and logAndThrow!(E = Exception)(...) (name to be determined) would log a critical message and throw the given exception/error with the same message. -SteveOn 07/03/12 09:25, Jonathan M Davis wrote:I don't see why the agitation around this particular matter. It's a matter of convenience, much like writeln (as opposed to just write). Let's admit that it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the thing is shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message = stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.On Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:+1. Is std.log a logging library or a complete error management library? If it's a logging library, the last thing it should be doing is affecting program flow. In the case of fatal, in particular, the program may need to do something else after logging the fatal error before terminating. You could argue that the program should do that before logging the fatal error, but I don't think that's nice semantics. On the other hand, if it's a complete error management library, it probably shouldn't be called std.log.On Tue, 6 Mar 2012, Jose Armando Garcia wrote:Agreed. The logging functions should _not_ throw.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.loggerI 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.
Mar 07 2012
On Wed, Mar 7, 2012 at 4:21 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Tue, 06 Mar 2012 19:59:09 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:seOn 3/6/12 4:31 PM, Geoffrey Biggs wrote:On 07/03/12 09:25, Jonathan M Davis wrote:On Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:On Tue, 6 Mar 2012, Jose Armando Garcia wrote: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.loggerI 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 tho=m+1. Is std.log a logging library or a complete error management library? If it's a logging library, the last thing it should be doing is affecting program flow. In the case of fatal, in particular, the progra=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.Agreed. The logging functions should _not_ throw.ermay need to do something else after logging the fatal error before terminating. You could argue that the program should do that before logging the fatal error, but I don't think that's nice semantics. On the other hand, if it's a complete error management library, it probably shouldn't be called std.log.I don't see why the agitation around this particular matter. It's a matt=tof convenience, much like writeln (as opposed to just write). Let's admi=hingthat it often happens that you want to log some troublesome stuff just before throwing an exception with essentially the same message, so the t=talis shown on the screen and also persisted in the log. Without a critical level, the pattern would be: string message =3D stuff() + ": " + moreStuff(); log.error(message); throw new Exception(message); It's nice to encapsulate this frequent pattern, hence: log.critical(stuff() + ": " + moreStuff()); If you want to log but not throw, use log.error. I don't think the response "dont use those libraries either" is meaningful.I think access to the fatal/critical logging level should not be coupled with throwing exceptions. =A0I have no problem with having critical or fa=convenience functions that throw and log, but it should not be a *requirement*, and it should not be the default. I'd combine these two levels into one (there is no semantic difference except one throws an exception and one throws an error), and if I got my way, log.critical(...) would log a message and logAndThrow!(E =3D Exception)(...) (name to be determined) would log a critical message and throw the given exception/error with the same message.Yes, I am leaning toward this idea. Give me some time to come up with a better API that would make this logAndThrow template possible (we need to hint the Logger implementation that it needs to flush). Thanks, -Jose-Steve
Mar 11 2012
On Tue, Mar 06, 2012 at 03:52:56PM -0800, Jose Armando Garcia wrote:On Tue, Mar 6, 2012 at 3:27 PM, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:[...] I don't like the current state of dlang.org docs either. There is little or no intro paragraph to explain what on earth the module is used for or why you should bother reading the rest of the page for the next hour or so. It also doesn't give any motivating examples (I'm thinking of std.range here) why this module is useful. I think a good intro is a must to good documentation. Include some code snippets to show typical usage of the module. How to change common settings. Some explanation of why the user might find the module helpful. It's OK to duplicate some docs here, within reason. It should also be concise without being uninformative. For example (from std.range): This module defines the notion of range (by the membership tests isInputRange, isForwardRange, isBidirectionalRange, isRandomAccessRange), range capability tests (such as hasLength or hasSlicing), and a few useful range incarnations. is concise, but not very informative. Why should the user care what a range is anyway? No explanation is given. Something like this may be a beginning to better documentation: This module defines the notion of a range. Ranges generalize the concept of arrays, lists, or anything that involves sequential access. This abstraction enables the same set of algorithms (see std.algorithm) to be used with a vast variety of different concrete types. For example, a linear search algorithm such as std.find works not just for arrays, but for linked-lists, input files, incoming network data, etc.. This module defines several templates (<!--insert list here-->)for testing whether a given object is a range, and what kind of range it is. It also lets you construct new ranges out of existing ranges. For example, retro lets you access a bidirectional range in reverse, cycle creates a range that is an endless repetition of the original range. ... ... Basically, you're writing an overview to the module, so highlight its main components, give some insight into why it's useful, etc., so that the user can make sense of the long list of declarations that follow. As it stands, std.range's page consists of a giant list of range-related declarations that gives no hint to the user as to how they all fit together. You basically have to wade through it until it somehow all "clicks" together. That is poor documentation. The overview should give some general categories of stuff that's found in the module (e.g. range tests, constructing new ranges, etc., as I've tried to do above in my one-shot attempt to improve std.range's docs). Include some examples of really clever stuff that you can do with the help of the module. Such examples are usually a very good way to get the user up-to-speed with what the module has to offer. T -- What doesn't kill me makes me stranger.On 3/7/12, Jose Armando Garcia <jsancio gmail.com> wrote:Yeah. I am not terribly happy how ddoc and dlang.org organizes the documentation. I have been thinking of duplicating a lot of the documentation to the top but I have two main objections that are holding back. 1. document duplication and 2. overloading the user with information. I would like the top of the document with enough information and example for the regular user to just start logging. They can later come back and read the whole thing when they want to configure and tweak things. Thoughts?http://jsancio.github.com/phobos/phobos/std_log.html#fileNamePrefixesThat was what I was looking for but I didn't find it at first. I think that info about what the defaults are ([program].[hostname].[user].[severity].log.[datetime].[pid]) might be useful somewhere at the top. But that's just my 2 cents..
Mar 06 2012
On 3/6/12 5:39 PM, H. S. Teoh wrote:I don't like the current state of dlang.org docs either. There is little or no intro paragraph to explain what on earth the module is used for or why you should bother reading the rest of the page for the next hour or so. It also doesn't give any motivating examples (I'm thinking of std.range here) why this module is useful. I think a good intro is a must to good documentation. Include some code snippets to show typical usage of the module. How to change common settings. Some explanation of why the user might find the module helpful. It's OK to duplicate some docs here, within reason. It should also be concise without being uninformative. For example (from std.range): This module defines the notion of range (by the membership tests isInputRange, isForwardRange, isBidirectionalRange, isRandomAccessRange), range capability tests (such as hasLength or hasSlicing), and a few useful range incarnations. is concise, but not very informative. Why should the user care what a range is anyway? No explanation is given. Something like this may be a beginning to better documentation: This module defines the notion of a range. Ranges generalize the concept of arrays, lists, or anything that involves sequential access. This abstraction enables the same set of algorithms (see std.algorithm) to be used with a vast variety of different concrete types. For example, a linear search algorithm such as std.find works not just for arrays, but for linked-lists, input files, incoming network data, etc.. This module defines several templates (<!--insert list here-->)for testing whether a given object is a range, and what kind of range it is. It also lets you construct new ranges out of existing ranges. For example, retro lets you access a bidirectional range in reverse, cycle creates a range that is an endless repetition of the original range. ... ... Basically, you're writing an overview to the module, so highlight its main components, give some insight into why it's useful, etc., so that the user can make sense of the long list of declarations that follow. As it stands, std.range's page consists of a giant list of range-related declarations that gives no hint to the user as to how they all fit together. You basically have to wade through it until it somehow all "clicks" together. That is poor documentation. The overview should give some general categories of stuff that's found in the module (e.g. range tests, constructing new ranges, etc., as I've tried to do above in my one-shot attempt to improve std.range's docs). Include some examples of really clever stuff that you can do with the help of the module. Such examples are usually a very good way to get the user up-to-speed with what the module has to offer.I strongly agree, particularly in the case of ranges which are not a familiar concept to many, but also with the general principle.
Mar 07 2012
On Tue, Mar 06, 2012 at 07:25:23PM -0500, Jonathan M Davis wrote:On Tuesday, March 06, 2012 13:08:42 Brad Roberts wrote:[...][...] +1. Logging functions are for ... logging? Not for managing errors. Leave it up to the user to define something like the following, if they're so inclined: void logAndAbort(T...)(string fmt, T args) { critical(fmt.format(args)); throw new CriticalError(...); } One shouldn't have to write a try/catch block just so one can log a critical message and continue doing whatever it is needs to be done. (For example, you might want to log a critical condition immediately to ensure the sysadmin sees the message, before proceeding to attempt self-recovery that *may* fail and crash the system, and thereby lose the ability to log a message.) Let the user decide whether or not to throw. T -- Why have vacation when you can work?? -- ECI 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.Agreed. The logging functions should _not_ throw.
Mar 06 2012
On Tuesday, March 06, 2012 18:19:23 Jose Armando Garcia wrote:Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things.No, because they affect the log level. The concept of throwing and the log level should be _completely_ separate. std.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log). Adding an extra function which logs and then throws the exception that it's given is fine, but that should have _nothing_ to do with the log level. Asserting or throwing unconditionally like std.log does now is completely unacceptable IMHO. Logging should _not_ affect program flow. - Jonathan M Davis
Mar 06 2012
On 3/6/12 7:04 PM, Jonathan M Davis wrote:On Tuesday, March 06, 2012 18:19:23 Jose Armando Garcia wrote:Why?Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things.No, because they affect the log level. The concept of throwing and the log level should be _completely_ separate.std.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?Adding an extra function which logs and then throws the exception that it's given is fine, but that should have _nothing_ to do with the log level.Why?Asserting or throwing unconditionally like std.log does now is completely unacceptable IMHO.Why?Logging should _not_ affect program flow.Why? Once again, the fallacy police finds you in violation of asserting the hypothesis as its own sustaining argument. Andrei
Mar 06 2012
On Tuesday, March 06, 2012 19:27:35 Andrei Alexandrescu wrote:On 3/6/12 7:04 PM, Jonathan M Davis wrote:Because the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.On Tuesday, March 06, 2012 18:19:23 Jose Armando Garcia wrote:Why?Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things.No, because they affect the log level. The concept of throwing and the log level should be _completely_ separate.Because as others have asserted, logging should not affect program flow. It's printing out messages to a log, which doesn't necessarily have _anything_ to do with throwing exceptions. It's merely for providing information about what the program is doing. If you have it throwing exceptions - _especially_ exceptions which are specific to it - you're conflating two separate concepts: logging to a log file and having the program report errors. They _can_ be related, but they often aren't. And when you _do_ throw an exception, why on earth would anyone want a LoggingException (or whatever std.log would call its exception type)? You want an exception which relates to what went wrong, not what threw it. The fact that you logged a message before throwing is incidental. Nothing that catches the exception is going to care. - Jonathan M Davisstd.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?
Mar 06 2012
On 3/6/12 7:43 PM, Jonathan M Davis wrote:Because the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.Then I guess you'd be well advised to use the function that "logs to the error log", not the one that "logs to the error log and then throws". No? I mean you're explaining how a screwdriver is not appropriate for pounding nails.It does, because, as I mentioned, frequently one is interested in logging erroneous events that are followed by a breakage of flow.Because as others have asserted, logging should not affect program flow. It's printing out messages to a log, which doesn't necessarily have _anything_ to do with throwing exceptions.std.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?It's merely for providing information about what the program is doing. If you have it throwing exceptions - _especially_ exceptions which are specific to it - you're conflating two separate concepts: logging to a log file and having the program report errors. They _can_ be related, but they often aren't.Well all I can say is they are in my experience. Some logging libraries have primitives that throw, some don't. I prefer a library that has the option in it because I use it all the time with glog.And when you _do_ throw an exception, why on earth would anyone want a LoggingException (or whatever std.log would call its exception type)? You want an exception which relates to what went wrong, not what threw it. The fact that you logged a message before throwing is incidental. Nothing that catches the exception is going to care.That I do agree with. Andrei
Mar 06 2012
On Tuesday, March 06, 2012 20:10:58 Andrei Alexandrescu wrote:On 3/6/12 7:43 PM, Jonathan M Davis wrote:Sure, but std.log appears to have built in whether an exception is thrown or not into the log level itself. The log level and whether an exception is thrown are not necessarily related. Having one log function which throws and another which doesn't is fine. It's the fact that this proposal ties the exceptions to the log levels which is the problem.Because the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.Then I guess you'd be well advised to use the function that "logs to the error log", not the one that "logs to the error log and then throws". No? I mean you're explaining how a screwdriver is not appropriate for pounding nails.Sure, you _may_ want to throw when you log, and having a way to do that in one command is fine. The problem is that you don't _always_ want to throw or not at a particular log level, and this std.log proposal ties to the two together.It does, because, as I mentioned, frequently one is interested in logging erroneous events that are followed by a breakage of flow.Because as others have asserted, logging should not affect program flow. It's printing out messages to a log, which doesn't necessarily have _anything_ to do with throwing exceptions.std.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?And the current proposal declares a CriticalException type which is thrown when logging at the critical level. So, while we may agree on this, the current proposal does not. - Jonathan M DavisAnd when you _do_ throw an exception, why on earth would anyone want a LoggingException (or whatever std.log would call its exception type)? You want an exception which relates to what went wrong, not what threw it. The fact that you logged a message before throwing is incidental. Nothing that catches the exception is going to care.That I do agree with.
Mar 06 2012
On Tue, 06 Mar 2012 23:10:58 -0500, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/6/12 7:43 PM, Jonathan M Davis wrote:As has been repeatedly pointed out, the fatal and critical levels are different levels than the error level. Also, they cannot be turned off. Access to those levels should not be coupled with throwing an exception. Convenience functions to log at those levels and then throw an exception are perfectly acceptable. They just shouldn't be the only/default mechanism. A screwdriver is not appropriate for driving nails, but neither is an explosive-tipped hammer. -SteveBecause the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.Then I guess you'd be well advised to use the function that "logs to the error log", not the one that "logs to the error log and then throws". No? I mean you're explaining how a screwdriver is not appropriate for pounding nails.
Mar 07 2012
On 7 March 2012 16:43, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Tuesday, March 06, 2012 19:27:35 Andrei Alexandrescu wrote:Surprisingly, I agree with the idea that fatal and critical shouldn't throw, or at least shouldn't throw by default, maybe a configuration option would allow for that functionality. Logging probably shouldn't affect program flow. Its possible that I may need to log a "critical" error, then do some graceful shutdown. In my opinion, critical and error should /not/ throw by default, however they should be able to get an optional Exception to throw, if that is appropriate behavior. -- James MillerOn 3/6/12 7:04 PM, Jonathan M Davis wrote:Because the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.On Tuesday, March 06, 2012 18:19:23 Jose Armando Garcia wrote:Why?Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things.No, because they affect the log level. The concept of throwing and the log level should be _completely_ separate.Because as others have asserted, logging should not affect program flow. It's printing out messages to a log, which doesn't necessarily have _anything_ to do with throwing exceptions. It's merely for providing information about what the program is doing. If you have it throwing exceptions - _especially_ exceptions which are specific to it - you're conflating two separate concepts: logging to a log file and having the program report errors. They _can_ be related, but they often aren't. And when you _do_ throw an exception, why on earth would anyone want a LoggingException (or whatever std.log would call its exception type)? You want an exception which relates to what went wrong, not what threw it. The fact that you logged a message before throwing is incidental. Nothing that catches the exception is going to care. - Jonathan M Davisstd.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?
Mar 06 2012
On 07.03.2012 7:54, James Miller wrote:On 7 March 2012 16:43, Jonathan M Davis<jmdavisProg gmx.com> wrote:Exception is a graceful shutdown, as it calls destructors & finally blocks while unrolling the stack.On Tuesday, March 06, 2012 19:27:35 Andrei Alexandrescu wrote:Surprisingly, I agree with the idea that fatal and critical shouldn't throw, or at least shouldn't throw by default, maybe a configuration option would allow for that functionality. Logging probably shouldn't affect program flow. Its possible that I may need to log a "critical" error, then do some graceful shutdown.On 3/6/12 7:04 PM, Jonathan M Davis wrote:Because the level that you log something at and what you want to do in terms of exceptions aren't necessarily related at all. It could easily be that you want to log something and then do some series of operations before throwing - even if the log level is the most severe level, and you intend to throw an Error to kill the program. And as others have pointed out, you might want to log a series of messages. Having std.log throw on the first one makes it so that you can't log any others.On Tuesday, March 06, 2012 18:19:23 Jose Armando Garcia wrote:Why?Fatal and Critical are exactly these continence functions... To reiterate. fatal will always assert and critical will always throw. It is impossible for the user to disable these things.No, because they affect the log level. The concept of throwing and the log level should be _completely_ separate.Because as others have asserted, logging should not affect program flow. It's printing out messages to a log, which doesn't necessarily have _anything_ to do with throwing exceptions. It's merely for providing information about what the program is doing. If you have it throwing exceptions - _especially_ exceptions which are specific to it - you're conflating two separate concepts: logging to a log file and having the program report errors. They _can_ be related, but they often aren't. And when you _do_ throw an exception, why on earth would anyone want a LoggingException (or whatever std.log would call its exception type)? You want an exception which relates to what went wrong, not what threw it. The fact that you logged a message before throwing is incidental. Nothing that catches the exception is going to care. - Jonathan M Davisstd.log shouldn't be declaring _any_ exception types unless they're related to setting up the logging (_none_ which relate to functions which log).Why?In my opinion, critical and error should /not/ throw by default, however they should be able to get an optional Exception to throw, if that is appropriate behavior. -- James Miller-- Dmitry Olshansky
Mar 06 2012
On Wed, 07 Mar 2012 02:33:05 -0500, Dmitry Olshansky <dmitry.olsh gmail.com> wrote:Exception is a graceful shutdown, as it calls destructors & finally blocks while unrolling the stack.You're assuming the program uses finally/scope exit blocks to do shutdown logic. This is not always the case. A library shouldn't force certain development styles. -Steve
Mar 07 2012
On 07.03.2012 16:34, Steven Schveighoffer wrote:On Wed, 07 Mar 2012 02:33:05 -0500, Dmitry Olshansky <dmitry.olsh gmail.com> wrote:I do and within the reason. Doing graceful shutdown logic in scope/finally/destructors or what the heck the top-most catch(Exception) is not just a good practice. Otherwise an unexpected exception on the way up leaves debris and destruction behind, and the whole point of graceful shutdown is lost. Yup, one can provide an alternative way of shutdown, yet one still has to think of unexpected exceptions. -- Dmitry OlshanskyException is a graceful shutdown, as it calls destructors & finally blocks while unrolling the stack.You're assuming the program uses finally/scope exit blocks to do shutdown logic. This is not always the case. A library shouldn't force certain development styles.
Mar 07 2012
On Tue, 06 Mar 2012 22:54:39 -0500, James Miller <james aatch.net> wrote:Surprisingly, I agree with the idea that fatal and critical shouldn't throw, or at least shouldn't throw by default, maybe a configuration option would allow for that functionality. Logging probably shouldn't affect program flow. Its possible that I may need to log a "critical" error, then do some graceful shutdown.I see this pattern emerging: try { critical("Connection aborted!"); } catch(LoggingException e) { } // do graceful shutdown ... throw SomeError("Connection aborted!"); -Steve
Mar 07 2012
On Wed, Mar 7, 2012 at 4:31 AM, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Tue, 06 Mar 2012 22:54:39 -0500, James Miller <james aatch.net> wrote:Or you can just: scope(exit) // do graceful shutdown error("connection aborted"); throw SomeError("connection aborted"); Or better yet: scope(exit) // do graceful shutdown //... logAndThrow!(Exception, Severity.error)("connection aborted");Surprisingly, I agree with the idea that fatal and critical shouldn't throw, or at least shouldn't throw by default, maybe a configuration option would allow for that functionality. Logging probably shouldn't affect program flow. Its possible that I may need to log a "critical" error, then do some graceful shutdown.I see this pattern emerging: try { =A0 critical("Connection aborted!"); } catch(LoggingException e) { } // do graceful shutdown ... throw SomeError("Connection aborted!");-Steve
Mar 11 2012
On Tuesday, March 06, 2012 19:10:14 Sean Kelly wrote:Sorry. For some reason I thought info was callable directly without the leading log portion.It _is_ callable that way. Just look at the example at the top: http://jsancio.github.com/phobos/phobos/std_log.html - Jonathan M Davis
Mar 06 2012
On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Okay, everyone, by the original schedule, the review period would have ended yesterday. However, I don't think it makes sense to start a vote right now, where several points are actively discussed. After discussing the situation with Jose, I think the best option is to extend the review period for another few days, until next Monday. Jose will try to answer any open comments so everybody can get a good idea of what the library does and what others expect it to do until the vote starts next week. Thanks for the comments and review so far, David
Mar 07 2012
On Wed, Mar 7, 2012 at 1:53 PM, David Nadlinger <see klickverbot.at> wrote:On Monday, 13 February 2012 at 15:50:05 UTC, David Nadlinger wrote:Thanks David! I will have to some time later today to answer some of the open questions.Barring any objections, the review period starts now and ends in three weeks, on March 6th, followed by a week of voting.Okay, everyone, by the original schedule, the review period would have ended yesterday. However, I don't think it makes sense to start a vote right now, where several points are actively discussed. After discussing the situation with Jose, I think the best option is to extend the review period for another few days, until next Monday. Jose will try to answer any open comments so everybody can get a good idea of what the library does and what others expect it to do until the vote starts next week.Thanks for the comments and review so far, David
Mar 07 2012
Unfortunately, the discussion has ground to a halt again, so consider this a friendly reminder that there is still one day left until the end of the review period. David
Mar 11 2012
On Sun, 11 Mar 2012 16:49:24 -0500, David Nadlinger <see klickverbot.at> wrote:Unfortunately, the discussion has ground to a halt again, so consider this a friendly reminder that there is still one day left until the end of the review period. DavidHas Jose updated anything?
Mar 11 2012
On Sunday, 11 March 2012 at 22:09:54 UTC, Robert Jacques wrote:Has Jose updated anything?Not sure what you mean – the latest state of the code is at https://github.com/D-Programming-Language/phobos/pull/432. I was more referring to the design-level discussions anyway, though. David
Mar 11 2012
On Sun, 11 Mar 2012 17:14:37 -0500, David Nadlinger <see klickverbot.at> wrote:On Sunday, 11 March 2012 at 22:09:54 UTC, Robert Jacques wrote:There was a bunch of discussions/suggestions and then silence from Jose. I assumed he was trying stuff out or thinking about it and would post an update to the newsgroup.Has Jose updated anything?Not sure what you mean – the latest state of the code is at https://github.com/D-Programming-Language/phobos/pull/432. I was more referring to the design-level discussions anyway, though. David
Mar 11 2012
On 3/11/12 4:49 PM, David Nadlinger wrote:Unfortunately, the discussion has ground to a halt again, so consider this a friendly reminder that there is still one day left until the end of the review period. DavidI thought more about the point made about mixing throwing and logging levels. I agree that it's awkward to e.g. log to critical without throwing etc. I personally think in that case you really want the error log, but hey, point taken. Here's a suggestion: * Don't throw from the critical log and don't abort from the fatal log. * Define the logging functions such that logging an exception will log its toString() and then throw the exception. * Regarding static import log = std.log, I suggest we keep course. Works? Andrei
Mar 11 2012
On Sun, Mar 11, 2012 at 05:28:44PM -0500, Andrei Alexandrescu wrote: [...]I thought more about the point made about mixing throwing and logging levels. I agree that it's awkward to e.g. log to critical without throwing etc. I personally think in that case you really want the error log, but hey, point taken. Here's a suggestion: * Don't throw from the critical log and don't abort from the fatal log. * Define the logging functions such that logging an exception will log its toString() and then throw the exception.[...] +1. I feel much more comfortable with this design. T -- Tell me and I forget. Teach me and I remember. Involve me and I understand. -- Benjamin Franklin
Mar 11 2012
On Sun, Mar 11, 2012 at 3:28 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/11/12 4:49 PM, David Nadlinger wrote:gUnfortunately, the discussion has ground to a halt again, so consider this a friendly reminder that there is still one day left until the end of the review period. DavidI thought more about the point made about mixing throwing and logging levels. I agree that it's awkward to e.g. log to critical without throwin=etc. I personally think in that case you really want the error log, but h=ey,point taken.I thought about this a lot too and right now I think that if we want to remove asserting from fatal and remove throwing from critical then we should just remove those log levels completely. To me they don't add any additional value. The whole point of having them in the first place was because of their assert and throw semantic.Here's a suggestion: * Don't throw from the critical log and don't abort from the fatal log. * Define the logging functions such that logging an exception will log it=stoString() and then throw the exception.This would be great if it made everyone happy but I think it would logger.info(e, "format message", ...); log the formatted message and the exception e. Ideally what I would like is= : enum Severity { fatal, error, warning, info }; // fatal cannot be disabled // none of the severity levels assert or throw and we have a template: logAndThrow!(FileNotFoundException, Severity.{fatal,error,warning,info})("formatted message", args...); logAndThrow logs the message, and throws a FileNotFoundException object with a message equal to the "formatted message". Unfortunately to implement this in a consistent way I would have to rethink the way the current "fa=E7ade" is designed/implemented.* Regarding static import log =3D std.log, I suggest we keep course. Works?I think there is currently too much disagreement on std.log. I am honestly too busy juggling family, friends, school and work. I am currently leaning towards removing std.log from the review queue and spending some time ironing out the details pointed in this thread. I would like to experiment with some things before making any real suggestions but I would really like to have a logging library that I use throw/assert for me as it would simplify my code. I would like to thank everyone that commented on the design as it was really helpful for me to understand everyone's point of view and expectations. Thanks! Thoughts? -JoseAndrei
Mar 11 2012
On Mon, 12 Mar 2012 01:05:33 -0400, Jose Armando Garcia <jsancio gmail.com> wrote:On Sun, Mar 11, 2012 at 3:28 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:This is fine, since we can always add more levels later if a need arises. -SteveI thought more about the point made about mixing throwing and logging levels. I agree that it's awkward to e.g. log to critical without throwing etc. I personally think in that case you really want the error log, but hey, point taken.I thought about this a lot too and right now I think that if we want to remove asserting from fatal and remove throwing from critical then we should just remove those log levels completely. To me they don't add any additional value. The whole point of having them in the first place was because of their assert and throw semantic.
Mar 12 2012
On Monday, 12 March 2012 at 05:05:43 UTC, Jose Armando Garcia wrote:I think there is currently too much disagreement on std.log. I am honestly too busy juggling family, friends, school and work. I am currently leaning towards removing std.log from the review queue and spending some time ironing out the details pointed in this thread. I would like to experiment with some things before making any real suggestions but I would really like to have a logging library that I use throw/assert for me as it would simplify my code.Okay, so let's remove std.log from the review queue without a vote for now. Be sure to let everybody know when you had a chance to work on it and you think it's time for resuming the review, even if this should already be next week; std.log will re-enter the queue then. Thanks to everyone, David
Mar 12 2012
On 3/12/12 5:35 PM, David Nadlinger wrote:On Monday, 12 March 2012 at 05:05:43 UTC, Jose Armando Garcia wrote:I think that's a wise decision, thanks Jose and David. One possibility is that Jose transfers the code to someone else who takes it through the review process and makes the appropriate amends. Jose would of course keep authoring credits, to which the new submitter would be added. Is anyone interested? Thanks, AndreiI think there is currently too much disagreement on std.log. I am honestly too busy juggling family, friends, school and work. I am currently leaning towards removing std.log from the review queue and spending some time ironing out the details pointed in this thread. I would like to experiment with some things before making any real suggestions but I would really like to have a logging library that I use throw/assert for me as it would simplify my code.Okay, so let's remove std.log from the review queue without a vote for now. Be sure to let everybody know when you had a chance to work on it and you think it's time for resuming the review, even if this should already be next week; std.log will re-enter the queue then. Thanks to everyone, David
Mar 12 2012
On Mon, Mar 12, 2012 at 4:01 PM, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 3/12/12 5:35 PM, David Nadlinger wrote:I have tried to document every major modification that the community has requested in Trello. I'll continue to work on std.log but if anyone thinks they can complete this faster than me, please go ahead and take over. Just let know. Thanks David and everyone else for your commitment to the the review process. -JoseOn Monday, 12 March 2012 at 05:05:43 UTC, Jose Armando Garcia wrote:I think that's a wise decision, thanks Jose and David. One possibility is that Jose transfers the code to someone else who takes it through the review process and makes the appropriate amends. Jose would of course keep authoring credits, to which the new submitter would be added. Is anyone interested?I think there is currently too much disagreement on std.log. I am honestly too busy juggling family, friends, school and work. I am currently leaning towards removing std.log from the review queue and spending some time ironing out the details pointed in this thread. I would like to experiment with some things before making any real suggestions but I would really like to have a logging library that I use throw/assert for me as it would simplify my code.Okay, so let's remove std.log from the review queue without a vote for now. Be sure to let everybody know when you had a chance to work on it and you think it's time for resuming the review, even if this should already be next week; std.log will re-enter the queue then. Thanks to everyone, DavidThanks, Andrei
Mar 12 2012
On 13 March 2012 12:34, Jose Armando Garcia <jsancio gmail.com> wrote:On Mon, Mar 12, 2012 at 4:01 PM, Andrei AlexandrescuJose, I haven't used Trello, but is it possible to open up this board publicly so we anybody can look at it? It would probably help if people want to contribute. Otherwise, you could start adding issues to Github that people can look at. -- James MillerI think that's a wise decision, thanks Jose and David. One possibility is that Jose transfers the code to someone else who takes it through the review process and makes the appropriate amends. Jose would of course keep authoring credits, to which the new submitter would be added. Is anyone interested?I have tried to document every major modification that the community has requested in Trello. I'll continue to work on std.log but if anyone thinks they can complete this faster than me, please go ahead and take over. Just let know. Thanks David and everyone else for your commitment to the the review process. -Jose
Mar 12 2012
On Mon, Mar 12, 2012 at 4:44 PM, James Miller <james aatch.net> wrote:On 13 March 2012 12:34, Jose Armando Garcia <jsancio gmail.com> wrote:I don't think I have access to do that in Trello. Anyone? Post you trello information here and maybe someone can give you access. Good idea. I'll move all the TODOs to GitHub's issues and let you know when it is there.On Mon, Mar 12, 2012 at 4:01 PM, Andrei AlexandrescuJose, I haven't used Trello, but is it possible to open up this board publicly so we anybody can look at it? It would probably help if people want to contribute. Otherwise, you could start adding issues to Github that people can look at.I think that's a wise decision, thanks Jose and David. One possibility is that Jose transfers the code to someone else who takes it through the review process and makes the appropriate amends. Jose would of course keep authoring credits, to which the new submitter would be added. Is anyone interested?I have tried to document every major modification that the community has requested in Trello. I'll continue to work on std.log but if anyone thinks they can complete this faster than me, please go ahead and take over. Just let know. Thanks David and everyone else for your commitment to the the review process. -Jose-- James Miller
Mar 12 2012
On Mar 12, 2012, at 7:28 AM, Andrei Alexandrescu wrote:On 3/11/12 4:49 PM, David Nadlinger wrote:endUnfortunately, the discussion has ground to a halt again, so consider this a friendly reminder that there is still one day left until the =levels. I agree that it's awkward to e.g. log to critical without = throwing etc. I personally think in that case you really want the error = log, but hey, point taken.of the review period. =20 David=20 I thought more about the point made about mixing throwing and logging ==20 Here's a suggestion: =20 * Don't throw from the critical log and don't abort from the fatal =log.=20 * Define the logging functions such that logging an exception will log =its toString() and then throw the exception.=20 * Regarding static import log =3D std.log, I suggest we keep course. =20 Works?+1 (I particularly like the idea of logging an exception rather than = logging a message and a separate exception to throw, which may contain a = different message.) Geoff=
Mar 12 2012