loguru
loguru copied to clipboard
How do I change the default display format of the logger
I like this powerful module very much, it is very simple to use, but I am having some trouble customizing the display format, I want to remove the main part of the default display, I tried add(), but if I set it to cause duplication of output information, I do not know how to solve, I use loguru in a multi-process program.
If I try to customize the display format in either of the following ways, I get repeated messages in my multiprocess program, no matter what level it is:
logger.add(sys.stdout, colorize=True, format="<green>{time:YYYY-MM-DD at HH:mm:ss}</green> | <level>{message}</level>")
or
logger.add(sys.stderr, format="{time} {level} {message}")
Hi @stevenhubhub. Did you try first to remove()
the default handler? This should avoid duplicated output.
Hi @stevenhubhub. Did you try first to
remove()
the default handler? This should avoid duplicated output.
Thanks for your reply, very helpful! However, I had another problem, I wanted to manually set different colors for different information levels, and here is my code, I found that after setting this, the WARING category message would repeat again, for some reason: logger.remove()
logger.add(stdout, level='INFO', colorize=True,
format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<w>{level}</w>-{message}")
logger.add(stdout, level='DEBUG', colorize=True,
format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<le>{level}</le>-{message}")
logger.add(stdout, level='SUCCESS', colorize=True,
format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<g>{level}</g>--{message}")
logger.add(stdout, level='WARNING', colorize=True,
format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<y>{level}</y>--{message}")
logger.add(stdout, level='ERROR', colorize=True,
format="{time:YYYY-MM-DD HH:mm:ss.SSS}-<r>{level}</r>--{message}")
I don't advise to add()
multiple handlers logging to stdout
. You should have only one configured handler for stdout
.
You're seeing repeated WARNING
message because each time logger.warning()
is called, the log message is processed by all handlers with a threshold level lower than WARNING
. That is, the handler you added with level="DEBUG"
will process all message with severity DEBUG
or above.
If you want to change the default colors, I suggest you use the level()
function instead:
logger.level("WARNING", color="<blue>")
I don't advise to
add()
multiple handlers logging tostdout
. You should have only one configured handler forstdout
.You're seeing repeated
WARNING
message because each timelogger.warning()
is called, the log message is processed by all handlers with a threshold level lower thanWARNING
. That is, the handler you added withlevel="DEBUG"
will process all message with severityDEBUG
or above.If you want to change the default colors, I suggest you use the
level()
function instead:logger.level("WARNING", color="<blue>")
Oh! Thanks for details and basic teaching. I got it, I will try the level()!
hey @stevenhubhub! I think this issue can be closed if it is solved for you.
earlier i was going to add my answer at SO, but now i have decided to paste it here...
All the examples here are concerned with stdlib's logging
module; so, this answer is for those facing it with external loguru
module.
Distribution code common to all following MWE's:
import sys # stdlib
from loguru import logger # external
# fmt = "<green>{time}</green> <level>{message}</level>"
sh_fmt = "<level>{message}</level>"
The better format is fmt
above, but for illustration purposes; 'will use a shorter one.
- Buggy Code
Erraneous double logging code:
This code is took from: loguru overview
logger.add(sys.stderr, level="INFO", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 18:04:43.004 | INFO | __main__:<module>:6 - STOP using stdout (print) for debgging!
STOP using stdout (print) for debgging!
- Trial-&-Error
Changing logger level, or equivalently only for this demo, remove thelogger.add()
entirely
logger.add(sys.stderr,level="WARNING", format=sh_fmt,)
logger.info("STOP using stdout (print) for debgging!")
2023-08-10 17:32:21.206 | INFO | __main__:main:12 - STOP using stdout (print) for debgging!
-
Cause:
Wrong method to define logger level & format. -
Fix:
(with correct way to )
import sys
from loguru import logger
logger.configure(handlers=[{"sink": sys.stderr, "format": "<level>{message}</level>"}])
logger.level("WARNING") # Edit: It just fetches info, not configures
logger.info("STOP using stdout (print) for debgging!")
STOP using stdout (print) for debgging!
earlier i was going to add my answer at SO, but now i have decided to paste it here...
All the examples here are concerned with stdlib's
logging
module; so, this answer is for those facing it with externalloguru
module.Distribution code common to all following MWE's:
import sys # stdlib from loguru import logger # external # fmt = "<green>{time}</green> <level>{message}</level>" sh_fmt = "<level>{message}</level>"
The better format is
fmt
above, but for illustration purposes; 'will use a shorter one.
- Buggy Code
Erraneous double logging code:
This code is took from: loguru overviewlogger.add(sys.stderr, level="INFO", format=sh_fmt,) logger.info("STOP using stdout (print) for debgging!")
2023-08-10 18:04:43.004 | INFO | __main__:<module>:6 - STOP using stdout (print) for debgging! STOP using stdout (print) for debgging!
- Trial-&-Error
Changing logger level, or equivalently only for this demo, remove thelogger.add()
entirelylogger.add(sys.stderr,level="WARNING", format=sh_fmt,) logger.info("STOP using stdout (print) for debgging!")
2023-08-10 17:32:21.206 | INFO | __main__:main:12 - STOP using stdout (print) for debgging!
Cause:
Wrong method to define logger level & format.Fix:
(with correct way to )import sys from loguru import logger logger.configure(handlers=[{"sink": sys.stderr, "format": "<level>{message}</level>"}]) logger.level("WARNING") # Edit: It just fetches info, not configures logger.info("STOP using stdout (print) for debgging!")
STOP using stdout (print) for debgging!
Thanks for those helpful details!
Hi @stevenhubhub. Did you try first to
remove()
the default handler? This should avoid duplicated output.
Hi @Delgan, would you please be so kind as to add information about the default handler in the README or documentation? Many loguru users I know have been confused by the default behavior when using loguru for the first time (e.g. mixed stderr/stdout, duplicated handler adding, etc.).
@dichen-cd There is a note about this in the Readme:
Note that you may also
remove()
a previously added handler by using the identifier returned while adding it. This is particularly useful if you want to supersede the defaultstderr
handler: just calllogger.remove()
to make a fresh start.
What improvement or clarification would you suggest? Should I also mention hat calling remove()
will avoid duplicated output?
@dichen-cd There is a note about this in the Readme:
Note that you may also
remove()
a previously added handler by using the identifier returned while adding it. This is particularly useful if you want to supersede the defaultstderr
handler: just calllogger.remove()
to make a fresh start.What improvement or clarification would you suggest? Should I also mention hat calling
remove()
will avoid duplicated output?
It's not about the remove()
method itself, but rather about the (to be) removed handler.
Users typically have no knowledge of this default handler, such as where it pipes to, what format it uses, or whether the message has color, etc.
Without such knowledge, a safe practice is to manually add a stdout/stderr handler, which can result in duplicated message output.
Therefore, I believe it would be beneficial to inform users about the default handler that is automatically created when importing loguru.
@dichen-cd Hum, the default handler is mentioned twice:
For convenience, it is pre-configured and outputs to
stderr
to begin with
And bellow:
This is particularly useful if you want to supersede the default
stderr
handler
Please let me know how I should rephrase it t make it more explicit.
I think it would be useful to add the logger.add(...)
line that would reproduce the default sink. That would allow users to use it as a baseline for replacing it with customized sinks.