www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - std.experimental.logger default log level is everything

reply Steven Schveighoffer <schveiguy gmail.com> writes:
This code outputs "tracing":

```d
void main()
{
     import std.experimental.logger;
     sharedLog.trace("tracing");
}
```

Why does this happen, because the default log level is `all`.

Why would this be a problem? Because if I'm writing a library, what I 
want to put into tracing is stuff like protocol packet contents, very, 
very fine grained checks/internal state, etc.

If someone uses my library, then they get tracing messages to stderr *by 
default*.

IMO, the default level should be either `off` (no logging) or `fatal`. I 
shouldn't see trace messages without opting in to logging.

It makes std.experimental.logger unusable inside a public library, or 
else I have to stick it behind a special dub configuration to enable it.

Thoughts?

-Steve
May 28
next sibling parent reply SealabJaster <sealabjaster gmail.com> writes:
On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
wrote:
 Thoughts?

 -Steve
Without some form of being able to distinguish between "log from app" and "log from library X/Y/Z", std.logger doesn't seem usable inside of libraries (maybe if the library is a framework, then you could get away with it possibly). https://docs.microsoft.com/en-us/dotnet/core/extensions/logging
May 28
next sibling parent SealabJaster <sealabjaster gmail.com> writes:
On Friday, 28 May 2021 at 17:57:27 UTC, SealabJaster wrote:
 https://docs.microsoft.com/en-us/dotnet/core/extensions/logging
Here's another, probably more up-to-date link https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-5.0
May 28
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/28/21 1:57 PM, SealabJaster wrote:
 On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer wrote:
 

 form of being able to distinguish between "log from app" and "log from 
 library X/Y/Z", std.logger doesn't seem usable inside of libraries 
 (maybe if the library is a framework, then you could get away with it 
 possibly).
 
 https://docs.microsoft.com/en-us/dotnet/core/extensions/logging
Unfortunately, std.experimental.logger doesn't seem to have a mechanism to filter logs based on source. I think adding a separate filtering system (I've used similar things like log4j, and written some myself) would be a huge undertaking. -Steve
May 28
next sibling parent reply ikod <igor.khasilev gmail.com> writes:
On Friday, 28 May 2021 at 18:48:56 UTC, Steven Schveighoffer 
wrote:
 On 5/28/21 1:57 PM, SealabJaster wrote:
 On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
 wrote:
 
...
 Unfortunately, std.experimental.logger doesn't seem to have a 
 mechanism to filter logs based on source. I think adding a 
 separate filtering system (I've used similar things like log4j, 
 and written some myself) would be a huge undertaking.

 -Steve
In my libraries I usually call tracing/loging with debug's like: debug(mylibrary) tracef(...); so by default library user will not see any log messages from library code. User have to enable debug=mylibrary in dub config or in makefile, so he become aware of the consequences.
May 28
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/28/21 3:09 PM, ikod wrote:

 In my libraries I usually call tracing/loging with debug's like:
     debug(mylibrary) tracef(...);
 
 so by default library user will not see any log messages from library 
 code. User have to enable debug=mylibrary in dub config or in makefile, 
 so he become aware of the consequences.
 
Sure, but you shouldn't have to do that. It's trivial to change the default log level in phobos and then libraries have a choice on how to support logging. Plus, things like info logging might not be correct to put behind a debug statement. For example, vibe-d always has logging enabled, but the default is reasonable. -Steve
May 28
prev sibling parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Friday, 28 May 2021 at 18:48:56 UTC, Steven Schveighoffer 
wrote:
 On 5/28/21 1:57 PM, SealabJaster wrote:
 On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
 wrote:
 

 Without some form of being able to distinguish between "log 
 from app" and "log from library X/Y/Z", std.logger doesn't 
 seem usable inside of libraries (maybe if the library is a 
 framework, then you could get away with it possibly).
 
 https://docs.microsoft.com/en-us/dotnet/core/extensions/logging
Unfortunately, std.experimental.logger doesn't seem to have a mechanism to filter logs based on source. I think adding a separate filtering system (I've used similar things like log4j, and written some myself) would be a huge undertaking. -Steve
You can still implement custom logger, that will allow filtering by source,check the documentation: https://dlang.org/phobos/std_experimental_logger.html It indeed might be useful to have a logger configurable by some file as a package in dub, and it can actually be integrated with existing api. It can either replace main logger or expose a custom logger, if necessary. Best regards, Alexandru.
May 28
prev sibling next sibling parent singingbush <singingbush hotmail.com> writes:
On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
wrote:
 IMO, the default level should be either `off` (no logging) or 
 `fatal`. I shouldn't see trace messages without opting in to 
 logging.
I agree, defaulting to LogLevel.all was a bad choice. I also think that std.experimental.logger shouldn't setup a logger by default. It's very easy for a user to opt in using `sharedLog = new MyLogger();` I'm happy for phobos to include a Logger implementation but the default behaviour should be to not output anything unless a Logger has been explicitly assigned to sharedLog.
May 28
prev sibling parent reply Mathias LANG <geod24 gmail.com> writes:
On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
wrote:
 [...]

 IMO, the default level should be either `off` (no logging) or 
 `fatal`. I shouldn't see trace messages without opting in to 
 logging.
Expectations vary depending on the developer. I, for one, would expect `Info` to be the default level, but would be surprised if I wrote code and it did nothing by default.
 It makes std.experimental.logger unusable inside a public 
 library, or else I have to stick it behind a special dub 
 configuration to enable it.

 Thoughts?

 -Steve
I think what makes `std.experimental.logger` unusable inside a public library is the lack of hierarchy. Tango had loggers that were object and hierarchical. Ocean has them too: https://github.com/sociomantic-tsunami/ocean/blob/v6.x.x/src/ocean/util/log/Logger.d We use them a lot in our app, e.g. having `this.log = Log.lookup(__MODULE__);` in the class' ctor. They can be configured to output to stdout, file(s), or any other output (e.g. Ocean has syslog support). In our unit tests, we save all log output to a circular buffer, which we print if an assert is triggered, this way we don't clutter the output of the run, but still provide detailed informations on (possibly spurious) failure. They can also be configured: https://github.com/bosagora/agora/blob/2809791954133da4c352d612d7347ee667e65312/doc/config.example.yaml#L172-L222 In our server app, we even have a control interface (bound to localhost) which allow us to dynamically reconfigure them. E.g. there was a bug recently, I just SSH into the machine and run `curl -X POST '127.0.0.1:3000/admin/logger?name=root&level=Trace&console=true'` (https://github.com/bosagora/agora/blob/2809791954133da4c352d612d7347ee667e65312/source/agora/ pi/Admin.d#L36-L42) and voila, everything is being logged out. Oh, and you can set a buffer that is to be used, so they don't keep on allocating.
May 30
parent reply Robert Schadek <rschadek symmetryinvestments.com> writes:
On Monday, 31 May 2021 at 00:42:50 UTC, Mathias LANG wrote:
 On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer 
 wrote:
 [...]

 IMO, the default level should be either `off` (no logging) or 
 `fatal`. I shouldn't see trace messages without opting in to 
 logging.
The amount of bug reports that lib would have gotten if it were off be default would properly be very large. To be frank, I would assume everybody replying to this thread, would have made a better job implementing a logger than I did all that time back, would be able to read the docs and insert a: ```D void main() { globalLogLevel = LogLevel.off; } ``` :-)
 I think what makes `std.experimental.logger` unusable inside a 
 public library is the lack of hierarchy. Tango had loggers that 
 were object and hierarchical.
 Ocean has them too: 
 https://github.com/sociomantic-tsunami/ocean/blob/v6.x.x/src/ocean/util/log/Logger.d
The docu is properly bad, but you can build hierarchies with MultiLogger.
May 31
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 5/31/21 5:03 AM, Robert Schadek wrote:
 On Monday, 31 May 2021 at 00:42:50 UTC, Mathias LANG wrote:
 On Friday, 28 May 2021 at 17:29:48 UTC, Steven Schveighoffer wrote:
 [...]

 IMO, the default level should be either `off` (no logging) or 
 `fatal`. I shouldn't see trace messages without opting in to logging.
The amount of bug reports that lib would have gotten if it were off be default would properly be very large.
I disagree completely. When people want to use something, they look at how to use it, and use it. If they use it wrong because they didn't read the directions, they *might* file a bug report, and if they do, you just post a RTFM response and move on. Most likely they post a message to d.learn and learn (or look it up on stack overflow or whatnot).
 
 To be frank, I would assume everybody replying to this thread, would 
 have made
 a better job implementing a logger than I did all that time back, would 
 be able to
 read the docs and insert a:
 
 ```D
 void main() {
      globalLogLevel = LogLevel.off;
 }
 ```
If someone does: ```d // note no import of std.experimental.logger main() { libraryFunction(); } ``` And gets log messages they didn't ask for, I think that would generate far more bug reports. Maybe not for logger, but for the poor library that decided to use it, as it likely has its name printing out with the log messages. And closing those bug reports with "you have to configure the logger away from the default" would not be met with blanket acceptance. The end result here is: no library is going to use it (including mine). -Steve
May 31
parent Robert Schadek <rschadek symmetryinvestments.com> writes:
On Monday, 31 May 2021 at 16:46:35 UTC, Steven Schveighoffer 
wrote:
 I disagree completely. When people want to use something, they 
 look at how to use it, and use it. If they use it wrong because 
 they didn't read the directions, they *might* file a bug 
 report, and if they do, you just post a RTFM response and move 
 on. Most likely they post a message to d.learn and learn (or 
 look it up on stack overflow or whatnot).
I have to disagree as well. The term RTFM exists because people don't read the manual.
Jun 06