Bug 24468 – stdThreadLocalLog does not print `log` and `trace` logs

Status
NEW
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2024-03-29T18:56:10Z
Last change time
2024-12-01T16:42:22Z
Assigned to
No Owner
Creator
Tomoya Tanjo
Moved to GitHub: phobos#9870 →

Comments

Comment #0 by ttanjo — 2024-03-29T18:56:10Z
I reproduce this issue with dmd 2.107.1 on Ubuntu 22.04 and run.dlang.io. I cannot reproduce this issue with `shaledLog`. # PoC code ```dlang import std.logger, std.stdio; void main() { writeln("==== stdThreadLocalLog ===="); stdThreadLocalLog.logLevel = LogLevel.all; stdThreadLocalLog.log("log"); stdThreadLocalLog.trace("trace"); stdThreadLocalLog.info("info"); stdThreadLocalLog.warning("warning"); stdThreadLocalLog.error("error"); stdThreadLocalLog.critical("critical"); writeln("==== sharedLog ===="); (cast()sharedLog).logLevel = LogLevel.all; (cast()sharedLog).log("log"); (cast()sharedLog).trace("trace"); (cast()sharedLog).info("info"); (cast()sharedLog).warning("warning"); (cast()sharedLog).error("error"); (cast()sharedLog).critical("critical"); } ``` # Expected output Both loggers print `all`, `trace`, `info`, `warning`, `error` and `critical` logs. ``` ==== stdThreadLocalLog ==== 2024-03-29T18:38:03.881 [all] onlineapp.d:16:main log 2024-03-29T18:38:03.881 [trace] onlineapp.d:17:main trace 2024-03-29T18:38:03.881 [info] onlineapp.d:9:main info 2024-03-29T18:38:03.881 [warning] onlineapp.d:10:main warning 2024-03-29T18:38:03.881 [error] onlineapp.d:11:main error 2024-03-29T18:38:03.881 [critical] onlineapp.d:12:main critical ==== sharedLog ==== 2024-03-29T18:38:03.881 [all] onlineapp.d:16:main log 2024-03-29T18:38:03.881 [trace] onlineapp.d:17:main trace 2024-03-29T18:38:03.881 [info] onlineapp.d:18:main info 2024-03-29T18:38:03.881 [warning] onlineapp.d:19:main warning 2024-03-29T18:38:03.882 [error] onlineapp.d:20:main error 2024-03-29T18:38:03.882 [critical] onlineapp.d:21:main critical ``` # Actual behavior `sharedLog` prints all the logs but `stdThreadLocalLog` lacks `all` and `trace` logs. ``` ==== stdThreadLocalLog ==== 2024-03-29T18:38:03.881 [info] onlineapp.d:9:main info 2024-03-29T18:38:03.881 [warning] onlineapp.d:10:main warning 2024-03-29T18:38:03.881 [error] onlineapp.d:11:main error 2024-03-29T18:38:03.881 [critical] onlineapp.d:12:main critical ==== sharedLog ==== 2024-03-29T18:38:03.881 [all] onlineapp.d:16:main log 2024-03-29T18:38:03.881 [trace] onlineapp.d:17:main trace 2024-03-29T18:38:03.881 [info] onlineapp.d:18:main info 2024-03-29T18:38:03.881 [warning] onlineapp.d:19:main warning 2024-03-29T18:38:03.882 [error] onlineapp.d:20:main error 2024-03-29T18:38:03.882 [critical] onlineapp.d:21:main critical ```
Comment #1 by kinke — 2024-03-29T22:25:48Z
According to the docs (https://dlang.org/phobos/std_logger_core.html#.stdThreadLocalLog), `stdThreadLocalLog` just forwards to `sharedLog`. The latter has a default LogLevel of info. So in your example, you'd need to set the `sharedLog.logLevel` *before* logging to `stdThreadLocalLog` (which defaults to `LogLevel.all`, forwarding everything to the shared logger). The key info is in the std.logger package docs (https://dlang.org/phobos/std_logger.html): > The LogLevel of the stdThreadLocalLog can be used to filter log calls before they reach the sharedLog Logger. Perhaps this should be duplicated in the documentation for the `stdThreadLocalLog` property.
Comment #2 by ttanjo — 2024-03-30T03:37:33Z
Thank you for the information. It works when I set `Loglevel.all` to both logger before calling logging methods as follows. ```dlang ... (cast()sharedLog).logLevel = LogLevel.all; stdThreadLocalLog.logLevel = LogLevel.all; writeln("==== stdThreadLocalLog ===="); stdThreadLocalLog.log("log"); ... ``` > Perhaps this should be duplicated in the documentation for the `stdThreadLocalLog` property. I guess the information of default logLevel in each logger should be in the `Thread Local Redirection` section in std.logger because most users read the documents in std.logger first. Can I close this issue or leave it opened until the document is improved? If the case of latter, I will send a pull request for it.
Comment #3 by forestix — 2024-05-28T23:13:54Z
The experience I had today as a newcomer to Phobos logging: - Read the std.logger docs. - Create a StdForwardLogger for each of my modules. (I want to control each module's log level separately.) - Discover that trace log messages are silently discarded. - Set my logger's log level. - Discover that trace log messages are still silently discarded. - Read the std.logger docs again. - Set globalLogLevel. - Discover that trace log messages are still silently discarded. - Read the std.logger docs again. - Set sharedLog.logLevel. - Discover that the compiler won't let me (none of the overloads of `logLevel` are callable using a `shared` mutable object) - Read the std.logger docs again. - Notice how much time this basic task is taking, and swear in exasperation. - Grovel through the dlang forum archive in search of help. - Find the magic incantation here: https://forum.dlang.org/post/[email protected] (cast()sharedLog).logLevel = LogLevel.all; - Try the magic incantation. - Discover that the compiler won't let me use it in @safe code. A default log level higher than `trace` is no surprise; that's reasonably common in logging libraries. However, dealing with it in Phobos is surprisingly painful. In particular, the solution has at least these problems: - It's nonintuitive. - It's not clearly documented. - It's unreasonably awkward for something as common as logging. - It doesn't work at all in @safe code. After finally getting to the bottom of it (and nearly giving up on D because this is far from the first Phobos usability problem to bite me) I see that I could work around it in my own programs by using @trusted code. However, I'm writing a library, and I really don't want to require that its users resort to library-specific functions or @trusted shenanigans to control such basic functionality as logging. It would be nice if this was either fixed by a revised std.logger design, or at least hidden behind a clearly documented standard interface.
Comment #4 by forestix — 2024-05-29T01:36:00Z
Also, is `(cast()sharedLog).logLevel = LogLevel.all` thread-safe? If so, how is the user supposed to know that? If not, where is the thread-safe equivalent?
Comment #5 by robert.schadek — 2024-12-01T16:42:22Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/9870 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB